A human deployment identity and an application runtime identity have different jobs. The notes API needs to read its own database secret; it does not need broad account administration or permission to delete the database.
The local evaluator is a deliberately small exact-match policy model. It teaches principal, action, resource, default denial and explicit-deny precedence. It is not the AWS IAM evaluator. Real authorization also involves role trust, policy types, conditions and organization controls described in the linked primary documentation.
Start from implicit denial. A matching allow grants the literal action/resource to the literal principal. A matching explicit deny wins even when an allow appears later. An unrelated deny does not deny every request in this small model.
Wildcards are rejected because their matching semantics are outside the exercise. That is a subset boundary, not a claim that real IAM cannot use wildcards. Do not deploy these fictional statements as AWS policies. The optional lab template has no IAM resource and no credentials.
from dataclasses import dataclass
import ipaddress
import re
class PlanError(ValueError):
pass
def bounded_text(value, label):
if not isinstance(value,str) or not value.strip() or len(value)>200:
raise PlanError(label)
return value
def integer(value, low, high):
if type(value) is not int or not low<=value<=high:
raise PlanError("integer outside plan bounds")
return value
@dataclass(frozen=True)
class Statement:
effect: str
principal: str
action: str
resource: str
def policy_decision(statements, principal, action, resource):
"""Exact-match teaching subset. Not the AWS IAM evaluator or policy simulator."""
if not isinstance(statements,(list,tuple)) or len(statements)>20:raise PlanError("bounded policy required")
for value in (principal,action,resource):bounded_text(value,"request field")
allowed=False
denied=False
for statement in statements:
if not isinstance(statement,Statement) or statement.effect not in ("Allow","Deny"):raise PlanError("typed effect required")
for value in (statement.principal,statement.action,statement.resource):
bounded_text(value,"policy field")
if '*' in value or '?' in value:raise PlanError("wildcards outside this teaching subset")
if (statement.principal,statement.action,statement.resource)==(principal,action,resource):
if statement.effect=="Deny":denied=True
else:allowed=True
if denied:return "explicit_deny"
return "allow" if allowed else "implicit_deny"
p=[Statement("Allow","api","read_secret","notes"),Statement("Deny","api","read_secret","notes")]
print(policy_decision(p,"api","read_secret","notes"))
print(policy_decision(p,"api","read_secret","other"))Least privilege is a concrete review of the work required, not merely an identity named “app.” The final plan allows one runtime role to read one secret. Additional grants are flagged even if the required permission also exists.
In real AWS, policy evaluation depends on the relevant identity/resource policies and may be constrained by boundaries or organization policies. The linked AWS reference covers those intersections. Our local model has no account or credential provider, so its result is educational evidence about the fixture only.
required=("runtime-role","read_secret","notes-secret")
requests=[required,("runtime-role","delete_database","notes"),("deployer","read_secret","notes-secret")]
for request in requests:
print(request[1], "allow" if request==required else "implicit_deny")Implement exact policy decisions and test deny precedence in both orders. Next bind the runtime’s nonsecret configuration to its intended workload identity and secret reference.