Policy Management¶
Define, test, and deploy authorization policies for your organization. This workflow is geared towards tech leads, security teams, and platform teams who need to control what members can do, where, and when.
Prerequisites¶
- An initialized organization (
auths org init) - Familiarity with Policy concepts
1. Write a policy¶
Policies are JSON files that combine predicates with boolean logic. Start with a baseline that most organizations need:
{
"And": [
"NotRevoked",
"NotExpired",
{ "HasCapability": "sign_commit" },
{ "MaxChainDepth": 2 }
]
}
This allows any active, non-expired member with the sign_commit capability to sign, as long as the delegation chain is at most 2 levels deep.
Common patterns¶
Restrict to specific repos:
{
"And": [
"NotRevoked",
"NotExpired",
{ "HasCapability": "sign_commit" },
{ "RepoIn": ["acme/frontend", "acme/backend", "acme/infra"] }
]
}
Require admin role for releases:
{
"And": [
"NotRevoked",
"NotExpired",
{ "HasAllCapabilities": ["sign_commit", "sign_release"] },
{ "RoleIs": "admin" }
]
}
Environment gating:
{
"And": [
"NotRevoked",
"NotExpired",
{ "HasCapability": "sign_commit" },
{ "EnvIn": ["staging", "development"] }
]
}
Branch protection:
{
"And": [
"NotRevoked",
"NotExpired",
{ "HasCapability": "sign_commit" },
{ "RefMatches": "refs/heads/feature/*" }
]
}
2. Lint¶
Check syntax before anything else:
3. Compile¶
Full validation with complexity checks:
Save the hash -- it's a content-addressable fingerprint of the policy, useful for auditing which version was active at any point in time.
4. Write tests¶
Create a test suite that covers your expected allow/deny scenarios:
[
{
"name": "active member can sign commits",
"context": {
"issuer": "did:keri:EOrg...",
"subject": "did:key:z6MkDev...",
"capabilities": ["sign_commit"],
"role": "member"
},
"expect": "Allow"
},
{
"name": "revoked member is denied",
"context": {
"issuer": "did:keri:EOrg...",
"subject": "did:key:z6MkDev...",
"capabilities": ["sign_commit"],
"revoked": true
},
"expect": "Deny"
},
{
"name": "member without capability is denied",
"context": {
"issuer": "did:keri:EOrg...",
"subject": "did:key:z6MkDev...",
"capabilities": [],
"role": "readonly"
},
"expect": "Deny"
},
{
"name": "wrong repo is denied",
"context": {
"issuer": "did:keri:EOrg...",
"subject": "did:key:z6MkDev...",
"capabilities": ["sign_commit"],
"repo": "acme/secret-repo"
},
"expect": "Deny"
}
]
Run the tests:
ok active member can sign commits: Allow (expected Allow)
ok revoked member is denied: Deny (expected Deny)
ok member without capability is denied: Deny (expected Deny)
ok wrong repo is denied: Deny (expected Deny)
4/4 passed
5. Diff before deploying¶
When updating a policy, compare the old and new versions to understand the impact:
Review HIGH-risk changes carefully -- they typically mean a safety check was removed.
6. Explain a decision¶
Debug why a specific action was allowed or denied:
Decision: DENY
Reason: CapabilityMissing
Message: Required capability 'sign_release' not found
Policy hash: a1b2c3d4e5f6...
Recommended workflow¶
flowchart TD
A["Write policy JSON"] --> B["auths policy lint"]
B --> C["auths policy compile"]
C --> D["auths policy test"]
D --> E{All tests pass?}
E -->|No| A
E -->|Yes| F["auths policy diff old new"]
F --> G{Review risk}
G -->|Acceptable| H["Deploy"]
G -->|Too risky| A
Keep policy files and test suites in version control alongside your code. Treat policy changes like code changes -- review, test, and merge via pull request.