Authentication
Every call except the public ones below sends Authorization: Bearer <token>.
Granite’s credentials carry no scopes: what a caller may do depends on which
kind of credential it presents. The scopes you see in requests and grants are
approval scopes you define, not permissions on Granite itself.
The three credentials
| Credential | Who holds it | Acts as |
|---|---|---|
| App credential | Your app’s server | Your app, asking about a person it names |
| ChirpAuth machine token | An agent or service with a ChirpAuth client Granite accepts | That client, asking about a person it names |
| Granite sign-in | A person, through the Granite web or Android app | That person |
App credential
Authorization: Bearer gas_...
x-granite-app-id: acme
x-user-id: sub_8Q3K2M11XZ
- Issued by Stackwell; see the Quickstart. Granite stores only its hash.
x-granite-app-idmust be the app the secret was issued to.x-user-idis required on every call, 1 to 128 characters, no control characters. Name the person by the ChirpAuth subject id (sub) your app received for them; only that ChirpAuth account can claim your requests (see Who owns a request). It names the person; it proves nothing about them.
ChirpAuth machine token
Authorization: Bearer <ChirpAuth machine token>
x-user-id: sub_8Q3K2M11XZ
- Accepted only from ChirpAuth clients Granite has been configured to accept. To have yours added, email support@granitegranted.com.
- Do not send
x-granite-app-id; Granite would treat the token as an app secret. x-user-idfollows the app credential’s rules when you send it. Send it when you act for a person: to file a request, create a connection, or verify a grant on someone’s behalf as an enforcer. Without it those calls are400. Leave it out when you act for nobody, such as verifying or revoking your own grant.- Your requests carry your ChirpAuth
client_idasrequester_app_id. - Same rights as an app credential. To revoke a grant, the grant’s
subject_chirp_submust also be your token’s subject.
Granite sign-in (people)
A ChirpAuth ID token issued to Granite’s own sign-in, which only the Granite web and Android apps obtain. Tokens issued to other ChirpAuth apps are refused. Your app does not use this credential; it is listed so you know what the person’s side can do.
What each credential allows
| Action | App credential or machine token | Granite sign-in |
|---|---|---|
| File a request, create a connection | Yes (needs write) | Yes, for themselves |
| Read a request | Only requests it filed | Only their own |
| Withdraw a request | Only requests it filed, while pending | No (they deny instead) |
| Approve or deny | No (403) | Only their own |
| List requests or grants | No (403) | Only their own |
| Verify a grant | Yes; see Checking a grant | Only their own grants |
| Revoke a grant | Only grants whose subject is the caller | Only their own |
| Give up all its grants for a person | Yes, with that person’s ID token for the caller’s own sign-in | No (they revoke each) |
| Export or delete account data | No | Only their own |
A request the app did not file, or a person does not own, reads as 404, the
same as one that does not exist.
No credential
These need no Authorization header:
| Path | What it is |
|---|---|
GET /health | Liveness |
GET /v1/transparency/jwks | Public key for decision signatures |
/consent/... | The approval pages a person opens in a browser; they sign in there |
curl -sS https://granitegranted.com/v1/approval-requests | grep -Fx '{"error":"unauthorized"}'