Create a key
A key is a key pair that you register with your organization. You keep the private key and use it to sign tokens. Code Storage stores only the public key. Open the Keys page in your organization dashboard and select Create key. New keys are unrestricted by default. To create a restricted key, enable Limit scope for this key. Deselect the scopes that the key does not need. If you leave every scope selected, the dashboard saves an unrestricted key. Your browser creates an ECDSA P-256 key pair and registers the public key. Copy the private key and your organization name.Organization name
The organization name is the token’siss claim, which Code Storage uses to find your registered
public keys. It is usually also the subdomain of the API host api.your-org.code.storage and the
Git host your-org.code.storage. The Settings page in the dashboard shows the exact API base
URL and Git host for your organization.
Store the private key
Store the private key in PKCS8 PEM format on your server or in a secret manager. The SDK clients and the examples on this page accept this format. SetPIERRE_PRIVATE_KEY to the PEM contents in your local environment or secret manager. The
examples read the key from this variable.
Set PIERRE_ORG to your organization name:
Token claims
Clients send the token with requests. They do not send the private key. The token header setsalg to the signing algorithm. It can also set kid to the ID of the
registered key. When kid matches a registered key, Code Storage checks the signature with that key
only. Otherwise, Code Storage tries each registered key of the organization.
A decoded token has a header and a set of claims. For example, this token reads and writes
team/project-alpha:
Set
exp on every token. Use the shortest practical lifetime and only the scopes that the operation
needs. A token can also carry ref policies that limit Git writes.
Scopes
Thescopes claim sets the operations that a token can perform. Each scope name must match exactly.
One scope does not include another.
git:write does not include read access. Add git:read when a client must clone or fetch before it
pushes. Tag deletion needs both git:read and git:write.
Repository claim
Therepo claim names the one repository that a token covers. The rules depend on the scopes:
- Set
repowhen the token hasgit:read,git:write, orrepo:write. Code Storage rejects such a token withoutrepo. repois optional when the only scope isorg:read.
{repo_name}, the path value must equal the repo claim exactly. Otherwise
the request returns 404 with the code repository_not_found, the same response as for a
repository that does not exist. So one repository-scoped token covers one repository. Percent-encode
a / in the path value, for example team%2Fproject-alpha.
POST /api/repos takes the name of the new repository from the repo claim. The optional body
field repo_name must equal the claim. Otherwise the request returns 400 with the code
repo_name_mismatch.
For example, this token lists the branches of team/project-alpha with
GET /api/repos/team%2Fproject-alpha/branches:
GET /api/repos. It has no repo claim:
Restricted keys
A restricted key has a scope allowlist,allowed_scopes. Its tokens can request only scopes from
that allowlist. A token does not get the allowed scopes automatically: its scopes claim must still
list each scope that the operation needs.
Tokens signed with a restricted key must meet these requirements:
- Include both
iatandexpas Unix timestamps in seconds. - Set
iatto the issue time. - Set
expafteriat, at most 3,600 seconds later. - Include only scopes from the key’s allowlist.
git:read and org:read can sign a token with only git:read. A
token that also includes git:write fails verification, even if the request needs only read access.
An unrestricted key has the allowlist ["*"] and no one-hour token lifetime limit. Its tokens must
still list valid scopes. * is not a valid token scope.
How to sign a JWT
The SDK signs and sends JWTs for you. These examples show how to sign an ES256 token for organization reads without using the SDK. They use a PKCS8 PEM private key from the dashboard and expire after one hour. If you use a restricted key, its allowlist must includeorg:read.
The examples read the organization name from PIERRE_ORG. For another operation, change the scopes
and add the repo claim if the operation needs it.
Install the signing library for your language:
Resolve token errors
An HTTP error response has acode and a detail. These responses come from a missing or incorrect
token:
For
Invalid or expired token, check these items:
- The signature uses a registered key, and
algis ES256, ES384, ES512, or RS256. issis your organization name.expis in the future.iss,sub, andscopesare present, and each scope name is in Scopes.repois present when a scope needs it. See Repository claim.- A token from a restricted key meets the restricted key requirements.