Skip to content
TDACorpIDENTITYSign in

Authorization

How a TDACorp product finds out whether a person may perform an action, by asking identity rather than reading a roles claim, and what the answers can be.

On this page

Authentication answers who a person is. Authorization answers what they may do. Identity does both, separately. A token proves identity. To find out whether an action is allowed, a product asks identity.

The reason for the split is that who you are changes rarely, and what you may do changes often. A role can be removed in a minute. A token issued five minutes ago would still say the old thing. So tokens say who you are, and the question "may this person do this, now" is asked fresh.

The shape of a question#

A question names three things.

  • The person. Usually by passing the token the person presented.
  • The action. A permission such as eidos.document.read. See Permissions and roles.
  • The organization the action is in, and optionally a resource, such as one document.

The answer is one of three.

AnswerMeaning
AllowAn assignment, a relation or a policy grants it, and nothing forbids it.
DenyThe question was evaluated and the answer is no.
IndeterminateIdentity could not safely work it out, for example because something it needed could not be loaded.

Allow and deny are not the only cases, and a product should not collapse the third into the second without thinking. A permission can say what to do when the answer is indeterminate: deny, or reuse a recent allow for the same question for at most 300 seconds, and otherwise deny.

How a decision is made#

In outline, identity does the following, in this order.

  1. Check who is asking. The calling product must itself be a registered client that is allowed to ask. A caller can only ask about people who belong to an organization that has an active installation of its product.
  2. Check the person and the token. The token must be current. A token that is out of date gets a deny with a hint to refresh it.
  3. Check the organization. The person must be an active member of an active organization.
  4. Check the action exists. An action the product never declared is denied.
  5. Check the installation. The product the action belongs to must be installed in the organization, and the action must be among the permissions the organization consented to. This only narrows: it never grants. Platform administration actions in the identity namespace are exempt.
  6. Gather what the person holds. Role assignments and direct grants in that organization, including those held through the groups the person belongs to, that have not expired or been revoked, and that are still backed by whoever delegated them.
  7. Look at the resource, if one was named, and what it sits inside.
  8. Apply policies. A policy can forbid something an assignment would allow. A forbid written in a parent organization also applies in its child organizations; a parent's permits do not.
  9. Decide. A forbid wins. Otherwise a match allows. Otherwise it is a deny.

Two properties follow.

  • Deny by default. Access nobody has been given is denied. So is an unknown action, and so is a person who is not an active member.
  • Forbid beats allow. Policies are the only thing that can say no to something an assignment grants.

Acting for someone#

A product can also ask with a delegated token, one that carries an act claim (see Delegation and token exchange). This works only while the pdp_subject_token flag is on, and the flag defaults OFF. The answer then also needs the acting products to be allowed into the organization and the action to be covered by the token's tdaid:agent_action entry. An act token with no such entry is denied.

Why a deny gives so little away#

To a product, a deny carries a single reason, access_denied. The detailed reason is available to an administrator. This is deliberate: a precise reason would let someone probe which people or organizations exist. A person who does not exist and one who is not a member get the same answer.

No roles claim#

Tokens do not carry roles. The access token has no roles claim and the discovery document does not advertise one. A product that used to read roles from a token must ask instead. See Sessions and tokens for what a token does carry.

Where the check happens#

The product that owns the resource enforces the answer. This is the policy enforcement point. Identity's authorization service is the policy decision point: it decides, and it never enforces for the product.

The identity SDK includes adapters for Next.js, Hono and Express that verify the access token and then ask the decision API. The SDK also verifies access tokens on a product's own API: the issuer, a single audience equal to the product's own identifier, the lifetime and the DPoP proof.

The adapter never invents an allow. The only allow it produces is one identity sent, either just now or, in the indeterminate case above, within the last 300 seconds. A token that fails verification is a deny.

Staying current#

An access token lives at most 15 minutes, and the answer to "may they" can change within that time. Tokens carry a version number for the person's authorization (av), and the answer carries the versions it was computed against. A product that caches an answer compares versions rather than trusting age alone. When something that should end access happens, such as a session being revoked for a security reason, the person's version advances, so older tokens and cached answers stop matching.

Calling it#

The decision API is not open to the public: the calling product authenticates as a registered client, with a token bound to its own key. Its endpoints are described in The authorization decision API.

Status: Available. The developer steps are in Protect your API.

Note

The SDK package, @tdacorp/identity-sdk, is on the public npm registry (first release 2.0.0). Status: Available.

Verified against commit c5ef357