Pre-release. v0.1 is not out yet, so there is nothing to install and no public source to clone — the quickstart builds from a checkout.
Tasks and task grants
A task is one piece of work an agent does for one person, against one audience. The first exchange creates it. It has its own expiry, separate from any token.
A task grant is what the agent uses to get new tokens for that task. It arrives in the
refresh_token field of the exchange response. It is bound to one task and one agent.
Two lifetimes
Section titled “Two lifetimes”An agent registration may set two limits:
{ "max_task_ttl": "PT30M", "max_token_ttl": "PT5M"}| Limit | Bounds | If not set |
|---|---|---|
max_task_ttl |
The whole task | SubactId:Tokens:DefaultTaskTtl, 30 minutes |
max_token_ttl |
Each token in the task | SubactId:Tokens:DefaultTokenTtl, 5 minutes |
Both are checked against the server-wide bounds SubactId:Agents:MinTaskTtl, MaxTaskTtl,
MinTokenTtl and MaxTokenTtl.
A long task holds only a short token, renewed as it goes. A leaked token is useful for minutes, not for the length of the task.
Each token lives for the shorter of max_token_ttl and what is left of the task, so the last
token of a 22-minute task lives two minutes, not five. A token never outlives its task.
The task’s lifetime comes from the registration, not from the subject token: a short-lived
session token can start a longer task. The human is checked again at every renewal. If tasks
should last no longer than the sessions that start them, set max_task_ttl to match.
What a refresh checks
Section titled “What a refresh checks”The refresh authenticates the agent exactly as the exchange did. Then, in order:
- The grant exists and belongs to this agent. Otherwise:
invalid_grant. - The task is not revoked. Otherwise:
access_denied. - The task has not expired. Otherwise:
access_denied. - The task has at least five seconds left. Otherwise:
access_deniedwith reasontask_ending. Stop; do not retry. - The human may still be acted for (see the sponsor check).
- The
resourceis the task’s audience. Otherwise:invalid_target. - The requested scope is within what the task holds. Otherwise:
invalid_scope. - The agent’s current registration still allows it.
It then issues a new token with the same task_id and a new jti.
The sponsor check
Section titled “The sponsor check”Subact ID keeps its own list of humans it will not act for. A human on that list is refused with
access_denied at every exchange and every refresh. SubactId:UpstreamIdp:SponsorCheck:Mode sets
how Subact ID learns who to refuse:
| Mode | What Subact ID does |
|---|---|
poll (default) |
Checks its list and asks the identity provider’s admin API (Keycloak’s) on every exchange and refresh. An exchange always asks fresh. A refresh may reuse an answer for up to SubactId:UpstreamIdp:SponsorCheck:CacheTtl (30 seconds by default), and never longer than the token being issued. If the provider cannot answer: temporarily_unavailable. |
signals |
Checks only its list. Operators add to it through the admin API; your identity provider can add to it through SCIM or Shared Signals. If nothing tells Subact ID, a task runs until it expires, which max_task_ttl bounds. |
Use signals when your identity provider has no admin API Subact ID can read.
In poll mode, a person disabled or deleted at the identity provider fails the next refresh of
every task, within one token lifetime. Back-channel logout and the CAEP session-revoked event
work in both modes: they end tasks but do not add the person to the list. See
revocation and
connecting your identity provider.
Refresh early
Section titled “Refresh early”Renew at about 60% of expires_in, not after a 401. @subactid/client does this for you and never
hands out a token that is about to expire.
When a task ends
Section titled “When a task ends”A task ends when it expires, when it is revoked, or when the agent stops using it. An expiry
sweeper marks expired tasks as ended, revokes their grants and writes one task.expired
record. Expiry is never recorded as a revocation.
© 2026 Nikola Živković PR Agencija za programerske usluge Novi Sad. Subact ID is its product.