Register your API as a resource, define permissions inside its namespace, and grant them through roles that can also hold the platform's own permissions.
ResourceYour application or API, bound one to one to an OAuth resource you have already registered. It supplies the namespace.
Your application or API, bound one to one to an OAuth resource you have already registered. It supplies the namespace.
NamespaceTwo to forty characters of a-z, 0-9 and hyphen, starting with a letter. It can never collide with the platform's own permission domains.
Two to forty characters of a-z, 0-9 and hyphen, starting with a letter. It can never collide with the platform's own permission domains.
Permission<namespace>:<action>, for example billing:invoices:void. Marked read-only or not, with a risk from 1 to 15 that feeds risk-based decisions.
<namespace>:<action>, for example billing:invoices:void. Marked read-only or not, with a risk from 1 to 15 that feeds risk-based decisions.
- RolesYour roles can combine your permissions with the platform's, through the same role API.
Who defines itA person holding the manage permission. An agent or an API key cannot define your vocabulary: the people who decide what a permission means are people.
A person holding the manage permission. An agent or an API key cannot define your vocabulary: the people who decide what a permission means are people.
# 1. Bind your API to a namespace
curl -X POST https://auth.zynthmedia.com/api/v1/authz/resources \
-H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
-d '{"oauth_resource_id": "7c0e3f2a-…", "namespace": "billing",
"description": "The billing API"}'
# 2. Define a permission: billing:invoices:void
curl -X POST https://auth.zynthmedia.com/api/v1/authz/resources/$RESOURCE_ID/permissions \
-H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
-d '{"action": "invoices:void", "description": "Void an issued invoice",
"read_only": false, "risk": 12}'Read the answer from a token you already verify, or ask live.
Token claimsAn access token minted for your API carries roles and permissions, filtered to your namespace. Verify it locally against the published keys.
An access token minted for your API carries roles and permissions, filtered to your namespace. Verify it locally against the published keys.
Use it whenYou want a decision with no network call per request.
POST /api/v1/authz/checkAny principal, with its own token, asks about itself only. Naming another principal answers 403.
Use it whenA client wants to know what it may do.
POST /api/v1/authz/service-checkYour resource server, with a client-credentials token holding the authz:check scope, asks about any principal in its tenant, member or agent. Up to 50 checks per call.
Your resource server, with a client-credentials token holding the authz:check scope, asks about any principal in its tenant, member or agent. Up to 50 checks per call.
Use it whenYour API decides on behalf of a caller, live.
curl -X POST https://auth.zynthmedia.com/api/v1/authz/service-check \
-H "Authorization: Bearer $SERVICE_TOKEN" -H "Content-Type: application/json" \
-d '{"checks": [
{"permission": "billing:invoices:void", "principal_id": "3f9a…"}
]}'
# → each result
{
"principal_id": "3f9a…",
"permission": "billing:invoices:void",
"allowed": true,
"via": "rbac",
"reason": "…",
"obligations": []
}A check is a question and not an act: it changes nothing and charges nothing. Denials are recorded as security telemetry, and the endpoint is monitored as an enumeration surface.
There is no separate code path for your vocabulary.
- AssignmentsGrant a role to a person, with an expiry if you want one.
- DelegationA person delegates a subset of what they hold to an agent, bounded and expiring.
- Attribute conditionsA permission can depend on attributes of the principal, the resource or the request.
- Why does this person have accessEvery decision can be explained: which role, which assignment, which delegation.
Standing privilege is how least privilege erodes. Access requests invert the default.
Access requestsA member asks for a role with a written justification and a duration of 1 to 90 days. A reviewer approves it for a bounded window, and the grant expires by itself. You can never decide your own request, and a pending request nobody decides expires after 14 days.
A member asks for a role with a written justification and a duration of 1 to 90 days. A reviewer approves it for a bounded window, and the grant expires by itself. You can never decide your own request, and a pending request nobody decides expires after 14 days.
Separation of dutiesDeclare mutually exclusive role sets. A grant of any role in a set is refused while the grantee holds another from the same set, wherever the grant comes from: the console, an invitation, a just-in-time approval or your directory's group sync.
Declare mutually exclusive role sets. A grant of any role in a set is refused while the grantee holds another from the same set, wherever the grant comes from: the console, an invitation, a just-in-time approval or your directory's group sync.
EvidenceEvery step (who asked, who decided, the exact grant) goes to the tamper-evident audit log and is mapped to SOC 2 CC6.1 to CC6.3 and ISO 27001 A.5.15 and A.5.18.
Every step (who asked, who decided, the exact grant) goes to the tamper-evident audit log and is mapped to SOC 2 CC6.1 to CC6.3 and ISO 27001 A.5.15 and A.5.18.