Team development secrets
Service Federation Cloud can fill the manual credentials declared by a
project during fed start. One teammate sets a value in the dashboard, or an
admin sets it with fed secrets set NAME. Other authorized teammates fetch it
without passing around an env file.
What the open-source CLI needs
Local stacks, worktree isolation, generated secrets, and scripts do not require a
Service Federation Cloud account. Cloud is an optional source for
type: secret, source: manual parameters.
Set up a team
- Sign in at app.service-federation.com with GitHub.
- Create an organization and a project. A Cloud project normally maps to one repository.
- Add teammates by email. New users receive an invite link.
- Add the development credentials the project needs.
Link a repository
fed login
fed link acme/web
git add .fed/cloud.yaml
git commit -m "Link fed development secrets"
For a new link, fed link writes .fed/cloud.yaml with
secret_cache: memory, the default cache policy. Re-linking preserves the
project's configured policy. Commit the file so every checkout points at the same Cloud
project and uses the same policy. If .gitignore ignores the whole
.fed/ directory, add an exception for .fed/cloud.yaml.
Sign-in works over SSH: open the printed URL on any machine, approve, and the
terminal finishes on its own. --no-browser skips the browser attempt and
just prints the URL. CI can supply
FED_TOKEN instead of storing credentials on disk.
Declare a manual secret
parameters:
STRIPE_SECRET_KEY:
type: secret
source: manual
description: "Development key from the Stripe dashboard"
Add STRIPE_SECRET_KEY in the Cloud dashboard. An organization admin can
also run fed secrets set STRIPE_SECRET_KEY. fed reads the value from stdin,
or asks for it with a hidden prompt. A linked and signed-in teammate can then run
fed start without creating a local env file first.
Private container images
To pull private team images, store one read-only registry token in the vault. Every
teammate's fed start then pulls those images without a personal
docker login.
1. Create a pull-only token
- GitHub Container Registry (
ghcr.io). Create a classic personal access token with only theread:packagesscope. Use a bot account if you can. - Docker Hub. Create an access token with read-only access.
- GitLab. Create a deploy token with only the
read_registryscope. - Amazon ECR. This does not work. ECR passwords expire after 12
hours. Keep using
aws ecr get-login-password | docker login.
2. Add the token to fed.yaml
parameters:
REGISTRY_TOKEN:
type: secret
source: manual
optional: true
description: Read-only token for team images on ghcr.io
registry_auth:
ghcr.io:
username: acme-bot
password: '{{REGISTRY_TOKEN}}'
Each key under registry_auth is a registry host. Set
username to the account that owns the token. The password
must reference a type: secret parameter. fed rejects a literal password,
because fed.yaml is committed to git.
3. Set the secret in the dashboard
Open the project in the dashboard. Under Development secrets, set
REGISTRY_TOKEN to the token. The name must match the parameter in
fed.yaml.
What fed does with the token
- When the token has a value, fed uses it only for pulls from that registry host. fed writes a temporary Docker config for the pull and deletes it afterwards.
- When the vault and the
env_filehave no value, fed pulls with each developer's own Docker login.optional: truekeepsfed startworking in that case. - When the registry rejects the token, fed prints a warning and retries with the developer's own login.
- Only
image:services use it. Base images that a Dockerfile pulls during abuild:still use the developer's own login.
Keep the token safe
Everyone with access to the project can read the token. So:
- Give it pull-only scope. A leaked token then cannot push or delete images.
- Create it on a bot account, not on a person's account.
- Rotate it on a schedule, and when someone leaves the project.
fed never runs docker login with the token and never writes it to
~/.docker.
Resolution and caching
A value from a declared env_file always wins. For each required manual
secret still missing locally, fed applies the linked project's cache policy:
memory(default). fed requests the values from the vault on every online start and keeps them only for the current process and its child services. Nothing is written to disk, and any file cache left by an earlier policy is removed.--offlineand unavailable-vault starts fail when a required manual secret is not available from anenv_file.file. A complete cache newer thanFED_VAULT_TTLcan satisfy the run without a vault request. The default TTL is five minutes. Otherwise fed requests the missing values from the vault and refreshes the owner-only.fed/secrets.cache.envfile. With--offline, or when the vault is unavailable, fed can use the last cached values regardless of age.
If a required value is still missing after applying the selected policy, startup stops and lists it.
The secret_cache setting controls fed's local handling of plaintext values;
it does not change how Service Federation Cloud stores them. The vault returns requested
plaintext values to an authorized CLI with Cache-Control: no-store and keeps
no in-process plaintext cache.
In file mode, fed writes the cache atomically with mode 0600 and manages
.fed/.gitignore. If the cache path becomes eligible for Git, fed disables
caching and removes an existing commit-eligible cache.
To enable the file cache for every checkout, set the linked project's shared policy in
.fed/cloud.yaml. A cloud.yaml without the key, including one
written by an older fed, uses memory mode.
org: acme
project: web
secret_cache: file
The --secret-cache file|memory flag overrides the committed policy for one
invocation. The policy applies only to values fetched from the team vault. It does not
change locally generated secrets in .fed/secrets.generated.env or values
supplied through an explicit env_file.
Removing access does not erase a laptop
Removing an organization member blocks their next server fetch immediately. It cannot
delete values already fetched to that person's machine. Under the file
policy those values can still support offline startup.
Rotate every credential the person could read. This is the only way to revoke a value that may already exist outside the service.
Security model
- Values are encrypted with AES-256-GCM before database storage. Each value uses a random nonce and row-bound authenticated data.
- Production deploys provision the encryption key from Scaleway Secret Manager into the application environment. It is absent from the database, repository, container image, and infrastructure state.
- The plaintext endpoint sends
Cache-Control: no-store. The application keeps no in-process plaintext cache. - Secret reads and changes are audited with the actor, names, and time. A change made with a CLI token also records which token, by its label. List responses and audit entries do not contain values.
- CLI bearer tokens can read the development secrets their owner can access and revoke themselves. If their owner is an organization admin, they can also set and delete that organization's secrets. They cannot manage members or tokens, create organizations or projects, or change billing.
- Only organization admins change secrets, in the dashboard or with
fed secrets set NAME. Members can read them.
Accepted limits
- The service can decrypt values. This is not end-to-end encryption.
- A CLI token is user-wide. If stolen, it can read every development secret its owner can reach across their organizations and projects. An admin's token can also overwrite or delete the secrets of every organization that person administers. Revoke a lost token from the dashboard.
- Cached values survive removal. Member removal stops new fetches but does not revoke copies already stored on a device under the
filepolicy. - Processes receive plaintext. The default memory-only cache mode avoids an intentional disk cache, but a child process can still log, swap, dump, or otherwise persist a value it receives.
- No production or compliance claim. There are no per-secret ACLs, scoped CI tokens, secret-version history, SOC 2 claim, or ISO claim.
Pricing and failure behavior
The first three people in an organization are free. Each additional seat costs €8 per
month. Billing only gates adding members. Billing state does not disable existing
memberships or secret reads, so it does not by itself block fed start.
A machine with a valid local cache under the file policy can keep using
those cached values while Cloud is unavailable. It cannot fetch rotations, new values, or
membership changes until the service returns. Under the default memory
policy, a start that needs a vault value waits for the service.