Developer docs · Browse & search
Keys and security
API keys and roles, tokens that expire, and what keeps keys and secrets safe.
API keys
Make a key on the Developer page of the console, or in code when signed in as an owner or administrator:
const { key, token } = await jwtson.keys.create({ name: 'CI', role: 'builder' }); // Store token now: it's shown once
for await (const each of jwtson.keys.list()) console.log(each.name, each.status, each.expiresAt);
await key.revoke(); // Stops it straight away, and runs it started stop at their next stepA key reaches this environment unless you pass reach: 'project' or 'organization', and lasts at most 90 days. With a key that reaches one environment, new Jwtson({ baseUrl, token }) is all you need.
| Role | Can |
|---|---|
viewer | Read |
operator | Also start, answer and stop runs |
builder | Also create and publish agents, workflows, schedules and triggers |
A few things always take a person who's an owner or administrator: making keys, granting rights, approving a webhook destination and managing providers.
Key formats, tools and limits
Keys look like jwtson_sk_... and end in a checksum, so a secret scanner can find a leaked one. To add one to yours, match jwtson_sk_[A-Za-z0-9_-]{43}[0-9a-f]{6}.
const { key, token } = await jwtson.keys.create({ name: 'Billing sync', requestsPerMinute: 600 });
for await (const key of jwtson.keys.list()) console.log(key.name, key.lastUsedAt);A key starts agents and workflows like a person does, but one that uses a tool or skill needs it given to the key first:
await key.allowTool('send_invoice');
await key.allowSkill('Weather');
await key.remove(toolOrSkillId); // Takes one backIt's one key and one tool or skill at a time, it lasts no longer than the key, and revoking the key ends it. A key that leaks can call what it was given until it's revoked, so give it only what it needs.
requestsPerMinute is the most a key can do if it leaks, until you revoke it. Going over gets a RateLimitError, and the client waits and retries for you where that's safe. There's no limit unless you set one. lastUsedAt is accurate to about a minute, so a key that's been idle for a long time is easy to spot and revoke.
Tokens
Pass a function if your token expires. It's asked for each request, and once more after a 401.
new Jwtson({ token: () => myAuth.currentToken() });Keeping keys safe
Use the SDK on your server. An API key in a web page or a mobile app can be read by anyone who has it.
- In a web page: the client refuses a fixed token. Your server signs its user in and gives the page a client session instead, so the key stays on your server.
- In transit: the address must be
https, except on this machine. Redirects are refused, so a token or secret isn't sent somewhere else. - In logs: a logged client doesn't show its token.
signingSecretand the token fromkeys.createare the two values to handle with care: each is given once. - The role: give each service its own key with the lowest role it needs. An
operatorkey can't define anything. - If one leaks: revoke it. It stops straight away, and runs it started stop at their next step.
A key sees only runs it started, and only inside its reach.
From the @jwtson/sdk README, as the code stands.