Documentation
Authentication
Indraft does not implement passwords, multi-factor authentication, account recovery, or session issuance. WorkOS AuthKit is the identity system of record, and Indraft is a resource server: it verifies, it does not issue.
Agents connect through OAuth
An MCP client discovers the authorization server from the protected-resource metadata at
/.well-known/oauth-protected-resource and completes an AuthKit flow. Indraft
verifies the issuer, the audience, and the algorithm on every request. A token minted for
a different resource is a perfectly valid AuthKit token and is refused here, because
accepting it would let any other service holding a token for the same user read your
workspace.
A connection can be revoked by a workspace administrator and takes effect on that connection's very next request. Waiting for a token to expire is a delay, not a revocation.
Your own code uses an API token
A token is shown once, when it is created, and stored only as a hash. Its effective permission is the INTERSECTION of its scopes and the current role of the member who created it, read live rather than stored: a token's power falls automatically when its creator is demoted, and nobody can mint a token that outranks them.
An agent connection is scoped like a token
The same intersection applies to an MCP connection. A grant carries the scopes it asked for, and its permission is those scopes intersected with the live role of the person who approved it. So an agent can be given less than you hold, it can never be given more, and it loses power the moment your role is lowered. There is no surface that is more trusted than another, and that is enforced in one place rather than promised twice.
Most clients ask for no scopes at all, because these names are ours rather than your
identity provider's and there is nothing for a client to have been offered. A connection
approved that way reads, writes, configures and can undo its own work: enough to be useful
on the first request, and still bounded by your role. What it does not get is everything
else on the list, which is crm:admin, data:export and workspaces:provision. Managing credentials, exporting the workspace and creating workspaces are deliberate
acts, so they need a token you minted on purpose rather than something you get by clicking
approve.
An agent can undo a change it made, and it cannot undo one you confirmed. Undo restores a field to what it was and refuses if the value has moved since; confirming a value does not move it, so a confirmation is checked separately and by name. You can still undo your own confirmation, because the rule is about who is acting rather than about what is being undone.
The one thing an agent cannot be granted at all is confirming a value. A confirmation means a person checked something, so the endpoint refuses any credential that is not a signed-in person, whatever scopes it carries.
What is on the record
Every change to your records is in the ledger: what changed, who changed it, when, and how they came by the value. That is the history the product is built around, and it covers writes from every surface.
Credentials keep their own account. A token records who created it, when, the scopes it holds, when it was last used, and when it was revoked; an agent connection records who approved it, its scopes, and when it was last used. So "who has access, and are they using it" is answerable at any time, for every credential in the workspace.
Membership and role history live in your identity provider, which is where that record belongs. Indraft keeps no second copy that could disagree with it.
Roles
| Owner | Everything, including billing and deleting the workspace. crm:read crm:write crm:configure crm:merge crm:revert members:manage credentials:manage billing:manage workspace:delete crm:erase data:export workspaces:provision |
| Admin | Everything except billing and deleting the workspace. crm:read crm:write crm:configure crm:merge crm:revert members:manage credentials:manage |
| Member | Works the records. Cannot reshape the schema or manage people. crm:read crm:write crm:merge crm:revert |
| Viewer | Read only. crm:read |
A role cannot grant a role it does not hold, and nobody can change their own. Membership lives in your identity provider; Indraft keeps no second copy that could disagree with it.
One decision, everywhere
The web application, REST, and MCP all reach the same authorization function. There is no surface that is more trusted than another, and the application cannot perform an operation the API would refuse, because it goes through the API like any other client.