Authentication
A request to Quillet's two APIs carries one of four credentials, and each route accepts only some of them.
Why the credential you mint must match the route
Access explains why Quillet has four credentials, a session, a personal token, a CLI key and a delivery key, and why ownership belongs to a person. This page covers the practical side. It shows how each credential is sent, which routes take it, and what the API answers when you send the wrong one. Read it before you write a script or a build step, so that the credential you mint is one the route will accept.
How each credential is sent and checked
How a credential is sent
- A session is what the dashboard uses. It signs in with
POST /api/v1/auth/loginand holds thequillet_sessioncookie, which your browser sends on every request. A script should not imitate this. Use a token or a key instead. - A personal token is sent with HTTP basic auth, with the token id as the user name and the secret as the password. Token ids start with
qt_. - A CLI key and a delivery key are sent with HTTP basic auth in the same way, using the key id and its secret. Key ids start with
qk_. The Keys page calls a CLI key's kind CLI.
With curl, that is -u '<id>:<secret>'. In any other client it is the header Authorization: Basic followed by the base64 of <id>:<secret>. Every secret is shown once, when it is minted, and never again.
Which route accepts which
| Routes | Session | Personal token | CLI key | Delivery key |
|---|---|---|---|---|
Personal tokens, /api/v1/auth/tokens |
yes | no | no | no |
| Listing and creating projects; listing members | yes | no | no | no |
| Adding and removing members | an owner | an owner | no | no |
| Changing project settings; creating, editing and deleting environments; keys, webhooks, search reindex | an owner | an owner | no | no |
| Reading the project and its environments | yes | yes | any CLI key of the project | no |
| Preview tokens | an editor or owner | an editor or owner | no | no |
| Content: documents, versions, publishing, schemas, folders, assets, translations, work queue, sync, import, compare, promote | by role | by role | by scope | no |
GET /api/v1/auth/me |
yes | yes | yes | no |
Delivery: content, list and search under /d/v1 |
no | no | no | yes |
A public file, /d/v1/<project>/assets/<id>, needs no credential at all. That is just as well, because an <img> sends none.
"By role" means the person's role in that project. A viewer reads, an editor writes and publishes, and an owner does both and also runs the project. "By scope" means the key's scopes: content:read to read, content:write to save and delete, and content:publish to publish and unpublish. A CLI key either works across every environment or is bound to one. A delivery key is always bound to one environment, and it reads published content only. With the assets:private scope it also gets signed links to private files.
What a refusal looks like
When the API refuses a request because of its credential, it answers with a small JSON object, { "error": …, "message": … }. The error is a code, and the message is a sentence you can show to a person:
- 401
unauthorized: there is no credential, or the API does not recognise the one sent. With no credential, the management API answersSign in to continue., and a personal token sent to delivery getsInvalid API key. - 403
forbidden: the credential is real, but it cannot do this. The message says why:This needs the owner role, which an API key never has.,This needs a person: sign in or use a personal token.,A delivery key can only be used on the delivery API., orThis key cannot read that environment. - 404
not_found: the project, the environment or the document does not exist, or this credential is not allowed to know that it does.
A token or key that has been revoked or has expired gets a 401 on its next request.
How to
Dashboard
- To mint a personal token, open the account menu in the header, choose Account, and press New token under Personal access tokens.
- To mint a key, open Settings, then Keys, and press New key. You need the owner role to do this.
- Choose the Kind: CLI for a script or a CI job, Delivery for a site or an app.
- Choose the Environment. A delivery key needs one, while a CLI key can have Every environment.
- Tick the Scopes. A delivery key always has
content:read. Tickassets:privateonly if the site serves private files. - Press Create key and copy the secret from Your new key. It is not shown again.
API
Before you store a credential, ask the API who it is:
curl -s -u '<keyId>:<secret>' http://localhost:3000/api/v1/auth/meFor a CLI key the answer is "kind":"key", with its project, its env (null when it works in every environment) and its scopes. For a personal token the answer is "kind":"user", with "via":"token".
To read published content, use a delivery key:
curl -s -u '<keyId>:<secret>' 'http://localhost:3000/d/v1/<project>/<env>/list'Send a CLI key to that same delivery route and the answer is the 403 This key cannot read that environment.
CLI
The CLI signs in with a personal token or a CLI key, never with a password. At a terminal it asks for the id and then for the secret. Before it stores the pair, it checks it against auth/me:
npx quillet login --api-url http://localhost:3000npx quillet whoami --api-url http://localhost:3000When there is no terminal, pass --key-id <keyId> and pipe the secret on standard input. In CI, set QUILLET_MANAGEMENT_KEY to <keyId>:<secret> instead of signing in.
Limits
- Only a person signed in to the dashboard can create or revoke personal tokens, create a project, list their own projects or list a project's members. A personal token gets a 401 or a 403 on those routes. An owner's token can still add and remove members, though, so a leaked owner's token can do that too.
- A CLI key never has the owner role. Keys, webhooks, members, changes to project settings, and creating, editing or deleting environments all need a person. The key can still read the project and its environments.
- A delivery key reads
/d/v1and nothing else, and only in one environment. - You cannot narrow a personal token to one project or to some scopes, and nobody can see another person's tokens.
- There is no OAuth flow for third-party apps. There is also no way to sign a request other than basic auth or the session cookie.
- Where a route has a rate limit, each token and each key spends its own budget. The budgets are listed on Configuration.
Related
- Access: why there are four credentials.
- Management API: the routes a token or a CLI key reaches.
- Delivery API: the routes a delivery key reaches.
- Your account: creating and revoking a personal token.
- Install and sign in: storing a credential for the CLI.
- How the parts fit: where each credential is used.