add error handling for policy configuration issues in authentication

This commit is contained in:
Eduardo Silva
2026-03-16 14:16:28 -03:00
parent e1f128f217
commit c707d278f3
5 changed files with 11 additions and 6 deletions

View File

@@ -84,11 +84,9 @@ def load_runtime_config(config_dir: Path) -> RuntimeConfig:
raise ValueError(f"Policy '{policy_name}' references unknown group '{group_name}'.") raise ValueError(f"Policy '{policy_name}' references unknown group '{group_name}'.")
for method_name in policy.methods: for method_name in policy.methods:
if method_name not in auth.auth_methods: if method_name not in auth.auth_methods:
logger.warning( msg = f"Policy '{policy_name}' references unavailable auth method '{method_name}'."
"Policy '%s' references unavailable method '%s' — policy forced to deny.", logger.error("CONFIG error: %s", msg)
policy_name, method_name, auth.policies[policy_name] = PolicyModel(policy_type="error", error_message=msg)
)
auth.policies[policy_name] = PolicyModel(policy_type="deny")
break break
return RuntimeConfig( return RuntimeConfig(

View File

@@ -53,9 +53,10 @@ class GroupModel(BaseModel):
class PolicyModel(BaseModel): class PolicyModel(BaseModel):
policy_type: Literal["bypass", "deny", "protected"] policy_type: Literal["bypass", "deny", "protected", "error"]
groups: list[str] = Field(default_factory=list) groups: list[str] = Field(default_factory=list)
methods: list[str] = Field(default_factory=list) methods: list[str] = Field(default_factory=list)
error_message: str | None = None
class AuthPoliciesFileModel(BaseModel): class AuthPoliciesFileModel(BaseModel):

View File

@@ -16,6 +16,7 @@ from auth_gateway.models.runtime import RuntimeConfig
class EffectivePolicy: class EffectivePolicy:
name: str name: str
mode: str mode: str
error_message: str | None = None
required_factors: list[str] = field(default_factory=list) required_factors: list[str] = field(default_factory=list)
allowed_users: set[str] = field(default_factory=set) allowed_users: set[str] = field(default_factory=set)
allowed_groups: set[str] = field(default_factory=set) allowed_groups: set[str] = field(default_factory=set)
@@ -43,6 +44,7 @@ def build_effective_policy(runtime_config: RuntimeConfig, policy_name: str) -> E
effective = EffectivePolicy( effective = EffectivePolicy(
name=policy_name, name=policy_name,
mode=policy.policy_type, mode=policy.policy_type,
error_message=policy.error_message,
allowed_users=expand_policy_users(runtime_config, policy), allowed_users=expand_policy_users(runtime_config, policy),
allowed_groups=set(policy.groups), allowed_groups=set(policy.groups),
) )

View File

@@ -23,6 +23,8 @@ async def auth_check(request: Request):
return PlainTextResponse("Application was not found.", status_code=403) return PlainTextResponse("Application was not found.", status_code=403)
effective_policy = get_effective_policy(runtime_config, context.policy_name) effective_policy = get_effective_policy(runtime_config, context.policy_name)
if effective_policy.mode == "error":
return PlainTextResponse(effective_policy.error_message or "Policy configuration error.", status_code=500)
if effective_policy.mode == "deny": if effective_policy.mode == "deny":
return PlainTextResponse("Access denied by policy.", status_code=403) return PlainTextResponse("Access denied by policy.", status_code=403)
if effective_policy.mode == "bypass": if effective_policy.mode == "bypass":

View File

@@ -64,6 +64,8 @@ async def login_page(request: Request, next: str = "/"):
context = resolve_context_from_request(request, runtime_config, next) context = resolve_context_from_request(request, runtime_config, next)
effective_policy = get_effective_policy(runtime_config, context.policy_name) effective_policy = get_effective_policy(runtime_config, context.policy_name)
if effective_policy.mode == "error":
return _render(request, "error.html", status_code=500, title="Configuration error", message=effective_policy.error_message or "A policy configuration error has been detected.")
if effective_policy.mode == "deny": if effective_policy.mode == "deny":
return _render(request, "error.html", status_code=403, title="Access denied", message="This route is blocked by policy.") return _render(request, "error.html", status_code=403, title="Access denied", message="This route is blocked by policy.")
if effective_policy.mode == "bypass": if effective_policy.mode == "bypass":