Write and test policy rules¶
Rules are Talmi's policy: they decide which principals may request which resources and actions. Everything is denied unless a rule allows it. This guide builds a rule from scratch and tests it without minting anything.
Before you begin¶
- At least one issuer and one provider (GitHub App or Artifactory) configured.
- The resources, actions, and rules model and conditions for background.
What a rule looks like¶
A rule has a match (which principals it applies to) and a list of allow statements (which resources and actions it
grants). Rules live under rules.d/.
- name: svc-a-read
match:
issuer: gh-actions # the issuer this rule applies to
condition:
repository: "my-org/svc-a" # match on principal attributes (token claims)
allow:
- resources: [ "ghes-corp:my-org/svc-a" ]
actions: [ "contents:read" ]
Authorization unions the allow statements of every matching rule. A request is granted only if that union covers every
requested resource=action, and never beyond the realm's
capability ceiling. A request that is not fully covered is denied as a whole.
1. Start with a read-only rule¶
Grant one repository read access to one issuer, as above. Reload the config (restart, or let the sync interval pick it up) and continue to testing.
2. Add a condition¶
A condition filters principals by their attributes. Use the short form for a single claim, or
all / any / not to combine them:
match:
issuer: gh-actions
condition:
all:
- repository: { in: [ "my-org/svc-a", "my-org/svc-b" ] }
- ref: "refs/heads/main"
If you prefer an expression, use expr instead of condition (not both):
match:
issuer: gh-actions
expr: 'ctx.repository startsWith "my-org/" && ctx.ref == "refs/heads/main"'
A rule with no condition matches nobody unless you set allow_empty: true, which matches every principal from the
issuer. This is deny-by-default: an empty condition is treated as "match none," not
"match all."
3. Test with explain¶
lease explain runs verify and authorize and shows the decision, without minting or auditing:
talmi lease explain \
--resource "ghes-corp:my-org/svc-a=contents:read" \
--token "$OIDC" --issuer gh-actions
The output shows which rules matched and, per requested resource, whether it was covered and why. Use --json for the
full trace.
4. Validate the config¶
config vet catches structural problems before they reach the server: unknown issuers or realms in a rule, actions a
realm cannot grant, malformed conditions:
Troubleshooting¶
- Everything is denied: no rule matches, or the condition is empty without
allow_empty. Confirm theissuername and the attribute names againsttalmi token inspect "$OIDC". action ... is not valid for realm: the action does not exist for that realm kind. See the realm's action grammar in Realm and provider types.- Covered by policy but
no provider can serve: policy allows it but no provider serves that resource; checktalmi provider list.
Next steps¶
- Reference: Rules and conditions, Conditions.
- Enable admin access uses rules with
talmi:*resources.