Skip to content
Console
Menu

Queues

Workflows

Getting Started

Authentication

KV Store

Keys and scopes

Secret and publishable keys, scoped to one environment and a set of scopes.

An API key authenticates a call. It has a kind, a mode and a list of scopes, and it is scoped to one organization, one project and one environment.

A key made for the organization as a whole is scoped to the organization alone: it has no project and no environment.

#The two kinds of key

A secret key begins sylphx_sk_live_ or sylphx_sk_test_, followed by a 20-character id, a 32-character secret and a 6-character checksum. It authenticates a call from a server, and you keep it there.

A publishable key begins sylphx_pk_live_ or sylphx_pk_test_, followed by an id. It carries no secret, and it is safe in a browser or a mobile app because it can hold only four scopes:

  • auth:public: read the environment's public auth configuration.
  • events:realtime:subscribe: subscribe to realtime events.
  • observability:ingest: send observability data, such as errors captured in a browser.
  • config:evaluate: read feature flag values for one user or device, never the rules behind them.

It cannot read or write your resources.

Never ship a secret key

Never put a secret key in client-side code. A browser or a mobile app gets a publishable key, which cannot read or write your resources even if someone reads it out of the bundle.

#What a key carries

FieldTypeWhat it is
kindstringWhether the key is a secret key or a publishable key.
modestring`live` or `test`, fixed in the key string when the key is made. A key may act only on an environment in the same mode.
scopesstring[]What the key may do, each scope naming a service and an action.
expire_timestringThe time after which the key stops working, when you set one.

A key also carries whether it has been revoked, and why. A reason is one of user, rotation, leaked, claimed, claim_expired, org_deleted, admin, role_changed or logout.

#Scopes

A scope names a service and an action, joined by a colon (<service>:<action>), so hosting:read reads a hosting resource and hosting:write changes one.

Every valid key holds access:whoami implicitly, whatever else it carries. You never have to grant it, and it cannot be granted: a create that asks for it is refused.

These are examples of the form, not the complete set: hosting:read, hosting:write, data:read, keys:use, secrets:write, events:write, billing:read, access:members:write, access:admin. A key may also hold the wildcards *:read and *:write, which cover every service the project has enabled.

A key can never hold a scope its creator does not hold: the scopes you ask for must be a subset of your own.

#Creating a key

A key lives under an environment, so --parent names the environment it belongs to.

bash
sylphx access api-keys create \
--parent orgs/{org}/projects/{project}/envs/production \
--spec.kind secret \
--spec.label ci \
--spec.scopes hosting:read,data:read

Add --dry-run to see what would be created without creating it. The commands you use by hand are sylphx access api-keys create, sylphx access api-keys revoke and sylphx access api-keys roll.

The secret is returned once, when the key is created or rolled. After that the key reports its id and the last four characters of the secret, and nothing more.

#Rolling a key

Rolling mints a new secret with the same scopes, and the old key keeps working until the grace period ends.

bash
sylphx access api-keys roll \
orgs/{org}/projects/{project}/envs/{env}/api_keys/{api_key}

The grace period is 24 hours by default, and you can set it with --grace-period; anything longer than 7 days is refused. A key that a secret scanner reports as leaked is not rolled at all: it is revoked at once, so the old secret stops working immediately.

#Sending a key

Send a key as the Authorization header: the word Bearer, a space, then the key.

bash
curl https://api.sylphx.com/v1/whoami \
-H "Authorization: Bearer $SYLPHX_API_KEY"

#A new key takes a moment

A brand-new key can take a moment to work. A call made in that moment fails with NOT_YET_PROPAGATED, which is retryable: send the call again. Errors covers that code and the rest.