Maturity: Limited preview. Grants ship and work. This page is an explainer
rather than a full reference, so it covers the model and what is answerable
today, not every option and error code.
What the user sees
The consent sheet is the whole trust surface. Your display name and logo come from the client directory, not from your request, so you cannot choose the words that describe you. Each capability you asked for appears as one plain line, written in the second person.connection
capability, with a 7-day standing grant selected. Reproduced from the shipped
component’s own stylesheet and copy, so the wording and colours match the app
rather than approximating it.
The duration control only appears when a standing grant is on offer, and the
note under it changes with the choice. Picking anything longer than a session
says plainly that the app can check while the user is away.
Two things follow from this that are worth designing around. Approval is
all-or-nothing, so a long capability list is one decision rather than several,
and asking for less makes the sheet easier to say yes to. And the sheet names
you, so a capability that is hard to justify in one line is one your users will
decline.
Why it is a second artifact
The model this replaces is the familiar one: an application holds an API key and queries a service about whoever it likes. That gives any integration a standing ability to ask about people who never agreed to be asked about, and the only control available is a policy saying don’t. A grant makes it structural instead. Two things are required for any question about a person, and neither substitutes for the other. Your M2M key carries the scopes your integration was granted. That is the ceiling on what you could ever ask. The grant is what this particular user allowed you to ask underneath that ceiling. A bare machine key resolves no person, and a grant alone opens no route. The ceiling is enforced in three places, which is why a misconfigured integration fails early rather than at the last step. The admin grant sets it, the device refuses to mint a grant for a capability you are not scoped for before any consent sheet appears, and the service checks it again on the way in.What you can ask today
membership never involves asking Array anything. The user proves it on their
device and you verify the proof, which is what the quickstart already does.
The last two rows are listed because they exist in the registry and an operator
deciding what your integration may ask will see them. Neither has a circuit or
a route yet, so nothing can answer them.
Pairwise sign-ins cannot ask anything. That is not a policy, it is a
consequence: a pairwise subject is a pseudonym no Array service can resolve, so
there is no question to put. If your integration needs to ask, it needs
disclosed mode.
Session and standing
By default a grant is session-lived. It lasts minutes, answers one ask, and is burned on use. An operation that makes two reads will getgrant_used on the
second, which is the burn working rather than a bug.
A user can instead approve a standing grant at consent time, up to the
per-capability cap above, which lets you ask again later without them present.
That is the case for a nightly job or a periodic recheck. Standing grants are
listed in the app and the user can revoke one at any time. Revocation works
because a grant is verified by an Array service rather than offline, so a
revocation check costs nothing.
A standing grant widens when you may ask, never what. The capability list
is fixed when it is minted.
Agreeing your capability set
We work through the capability set with each relying party rather than handing
out a default. Which capabilities your integration needs, whether any of them
should be standing and for how long, and whether disclosed mode is justified at
all are decisions we would rather make with you than have you discover through
refusals.
membership is proved on the device and costs
no grant at all. Starting from the smallest set that works is also the easiest
position to explain to your own users on the consent sheet, which shows them
exactly what they are approving.
Requesting one
Name the capabilities in the sign-in request, and the device folds them into the same consent sheet:verifyGrantToken from the RP server SDK, passing
expectedMode: "disclosed". A grant in the other mode is refused as
grant_invalid. Asking
array-api then uses @vibechecklabs/array-protocol-server, which presents the
grant with a fresh proof that you hold your registered key.
Full reference for both, including every refusal code, lands in a later release
of this guide. Until then, ask us.