diff --git a/containers/auth-gateway/auth_gateway/config_loader.py b/containers/auth-gateway/auth_gateway/config_loader.py index cbc791a..ee45e1c 100644 --- a/containers/auth-gateway/auth_gateway/config_loader.py +++ b/containers/auth-gateway/auth_gateway/config_loader.py @@ -84,11 +84,9 @@ def load_runtime_config(config_dir: Path) -> RuntimeConfig: raise ValueError(f"Policy '{policy_name}' references unknown group '{group_name}'.") for method_name in policy.methods: if method_name not in auth.auth_methods: - logger.warning( - "Policy '%s' references unavailable method '%s' — policy forced to deny.", - policy_name, method_name, - ) - auth.policies[policy_name] = PolicyModel(policy_type="deny") + msg = f"Policy '{policy_name}' references unavailable auth method '{method_name}'." + logger.error("CONFIG error: %s", msg) + auth.policies[policy_name] = PolicyModel(policy_type="error", error_message=msg) break return RuntimeConfig( diff --git a/containers/auth-gateway/auth_gateway/models/auth.py b/containers/auth-gateway/auth_gateway/models/auth.py index fdc73b3..127cd06 100644 --- a/containers/auth-gateway/auth_gateway/models/auth.py +++ b/containers/auth-gateway/auth_gateway/models/auth.py @@ -53,9 +53,10 @@ class GroupModel(BaseModel): class PolicyModel(BaseModel): - policy_type: Literal["bypass", "deny", "protected"] + policy_type: Literal["bypass", "deny", "protected", "error"] groups: list[str] = Field(default_factory=list) methods: list[str] = Field(default_factory=list) + error_message: str | None = None class AuthPoliciesFileModel(BaseModel): diff --git a/containers/auth-gateway/auth_gateway/services/policy_engine.py b/containers/auth-gateway/auth_gateway/services/policy_engine.py index 0d85a55..9024062 100644 --- a/containers/auth-gateway/auth_gateway/services/policy_engine.py +++ b/containers/auth-gateway/auth_gateway/services/policy_engine.py @@ -16,6 +16,7 @@ from auth_gateway.models.runtime import RuntimeConfig class EffectivePolicy: name: str mode: str + error_message: str | None = None required_factors: list[str] = field(default_factory=list) allowed_users: 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( name=policy_name, mode=policy.policy_type, + error_message=policy.error_message, allowed_users=expand_policy_users(runtime_config, policy), allowed_groups=set(policy.groups), ) diff --git a/containers/auth-gateway/auth_gateway/web/auth_routes.py b/containers/auth-gateway/auth_gateway/web/auth_routes.py index cbfa8bf..6b2ffc3 100644 --- a/containers/auth-gateway/auth_gateway/web/auth_routes.py +++ b/containers/auth-gateway/auth_gateway/web/auth_routes.py @@ -23,6 +23,8 @@ async def auth_check(request: Request): return PlainTextResponse("Application was not found.", status_code=403) 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": return PlainTextResponse("Access denied by policy.", status_code=403) if effective_policy.mode == "bypass": diff --git a/containers/auth-gateway/auth_gateway/web/login_routes.py b/containers/auth-gateway/auth_gateway/web/login_routes.py index badf38e..387f915 100644 --- a/containers/auth-gateway/auth_gateway/web/login_routes.py +++ b/containers/auth-gateway/auth_gateway/web/login_routes.py @@ -64,6 +64,8 @@ async def login_page(request: Request, next: str = "/"): context = resolve_context_from_request(request, runtime_config, next) 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": return _render(request, "error.html", status_code=403, title="Access denied", message="This route is blocked by policy.") if effective_policy.mode == "bypass":