The stone repository
Cloning your stone
One organisation and one repository per tenant on our git host, with a token that reaches only that repository. Decided, not built.
Planned Decided and written down. Not built, or built and not yet released. Do not integrate against it until the card says live.
What it does
Nothing yet. This card describes a decision, so that nobody builds against a guess.
The shape: each tenant gets its own organisation on our git host, holding a private repository called stone, plus a machine user that belongs to that one organisation and a token issued to that user.
Isolation comes from membership, not from the token's permissions. Git tokens narrow what a token may do, never where; "cannot read another tenant's repository" is only true if the account holding the token belongs to one organisation.
The clone URL, the username and the token are read from an endpoint on the account service, never derived. The organisation name is computed from the tenant id, and a collision changes how it is computed, so a caller that derives it will be wrong for exactly the tenants it matters for.
That endpoint answers to a signed-in session only. A gateway key of any scope is refused: a key that spends money must not also read git.
The token can be rotated, which issues a new one and then removes the old. A rotation that half-fails leaves the new token working rather than none.
Inputs and outputs
| Read the repository | GET /api/developer/stone, with your session. Returns the organisation, the repository, the clone URL, the web URL, the default branch, the machine username, the token, a token prefix, when it was rotated, and a status. |
|---|---|
| While it is being created | 202 with a Retry-After. |
| Rotate | POST /api/developer/stone/rotate, empty body. Same shape back, with the new token. |
| With a gateway key | 403 jwt_required. |
| Not configured on the deployment | 503 stone_not_configured. |
Configuration
| Clone | git clone https://<username>:<token>@git.prima.li/<org>/stone.git, with the organisation and username taken from the endpoint. |
|---|---|
| Rotation rate | One rotation per minute per tenant. Beyond that, 429. |
| Cached credentials | A client that has cached the token re-fetches once and retries once when git reports an authentication failure. |
Limits
- Not built. The provisioning side is decided and written down; the first task on it is a probe that records what the git host's API actually does, before any of it is written.
- Several details in the decision are asserted from the git host's published API rather than measured against ours, including the exact way a token is created and whether a token alone works in the clone URL without a username. The username-and-token form is the one to use until that is checked.
- Existing repositories created before this shipped sit under a single shared service account and are migrated by a script that requires a hand-written mapping. There is no automatic answer for a person who belongs to more than one workspace.
- The token is returned on every read to a signed-in member, not once. "Shown once" is how the portal chooses to present it, not a property of the endpoint.
Example
the clone, once the endpoint has answered
git clone https://<username>:<token>@git.prima.li/<org>/stone.git Source of truth
philosophers_stone/operations/decisions/0037-stone-per-tenant-forgejo-org-and-token.md (naming, the machine user, the endpoints and their status codes, rotation, the migration script, the verify-at-build list)philosophers_stone/operations/prima-onboarding-implementation-plan.md § W7