Secrets
What Aetherfy secrets are
A secret on Aetherfy is a named value — an API key, a database URL, a signing token — that Aetherfy stores encrypted at rest and injects into your agent’s machine as a plain environment variable at deploy or run time.
Your code reads them exactly as it reads any environment variable. There is no SDK call and no fetch step.
Values are never readable back. The Aetherfy CLI and API return only keys and metadata. Once you set a secret you cannot retrieve its value from Aetherfy by any route — if you lose it, rotate it at the source and set it again.
The two secret scopes on Aetherfy
Every Aetherfy secret has exactly one scope.
| Scope | Visible to | Set with |
|---|---|---|
| Agent-scoped | One agent | afy secrets set <agent> KEY=value |
| Workspace-scoped | Every agent in that workspace | afy secrets set --workspace <workspace> KEY=value |
When both scopes define the same key, the agent-scoped secret wins — it overrides the workspace-scoped value for that agent only. Every other agent in the workspace continues to see the workspace value.
That precedence is the intended way to give one agent a different credential from its siblings without splitting the workspace or duplicating the shared secrets across every agent.
Both scopes are settable from either surface. This page shows the CLI throughout; the dashboard offers the same two scopes and lists every secret with the agent or workspace it belongs to, at app.aetherfy.com/dashboard/secrets . The precedence rule above is enforced at deploy time and applies whichever surface set the secret.
Setting and listing Aetherfy secrets
Set one or more secrets on an agent in a single command:
afy secrets set my-agent API_KEY=sk-xxxxx DB_URL=postgres://user:pass@host/dbSetting a key that already exists updates it — Aetherfy treats this as an upsert, not an error.
To keep a value out of your shell history and out of the process list, pipe it in instead:
echo "sk-xxxxx" | afy secrets set my-agent API_KEY --stdinList the keys Aetherfy holds for an agent. Only keys and metadata come back, never values:
afy secrets list my-agentAetherfy enforces no limit on the number of secrets an agent may have, and no maximum value size.
Workspace-scoped Aetherfy secrets
Secrets shared by every agent in a workspace are set against the workspace rather than an agent:
afy secrets list --workspace my-workspace
afy secrets set --workspace my-workspace SHARED_API_KEY=sk-xxxxx
afy secrets delete --workspace my-workspace SHARED_API_KEYAn agent belongs to at most one workspace, declared with the workspace field
in aetherfy.yaml:
name: my-agent
runtime: python3.12
workspace: my-workspaceWorkspace names on Aetherfy are immutable after creation, so a workspace-scoped secret’s audience is stable — moving an agent means changing which workspace it declares, not renaming the workspace.
Deleting an Aetherfy secret
afy secrets delete my-agent API_KEYafy secrets delete always asks for confirmation on Aetherfy. There is
deliberately no --force flag on it, so it cannot be made silent in a script.
Secret key rules on Aetherfy
| Rule | Detail |
|---|---|
| Length | 1–255 characters |
| First character | A letter or an underscore |
| Remaining characters | Letters, digits, _, and - |
| Key | Valid on Aetherfy |
|---|---|
API_KEY | Yes |
_INTERNAL_TOKEN | Yes |
db-url-2 | Yes |
2ND_KEY | No — starts with a digit |
MY.KEY | No — . is not allowed |
Reserved names Aetherfy rejects
The rule is the prefix, and only the prefix: every key beginning AETHERFY_
is rejected, in any letter case, whether or not Aetherfy currently injects a
variable by that name. There is no list of individually-blocked names to check
against — if it starts with AETHERFY_, you cannot set it.
That is deliberately broader than the set Aetherfy injects today. The prefix belongs to the platform, so a variable added in a future release can never collide with a secret you already set.
The variables Aetherfy does inject, and which your code can read, are listed on /agents/task-contract.
If you need your own value for something in that space, give it a different
name — OPENAI_API_KEY or MY_API_KEY rather than AETHERFY_API_KEY.
Changing a secret does not redeploy an Aetherfy agent
This is the most important operational fact on this page, and the one most likely to cost you an hour.
Changing a secret on Aetherfy does not redeploy or restart a running agent. Secrets are injected when a machine is created, so a machine that already exists keeps the values it was created with for its whole life. A new value takes effect on the next deploy.
| Agent type | How the new value takes effect |
|---|---|
service | On its next deployment — see the three ways below. Nothing else changes it |
job | On the next run. Aetherfy sees that the machine it would have reused was created from a different secret set, and creates a new one with the current values instead — so that run pays a cold start |
A job agent therefore needs no action to pick up a new secret, but it is not
free: until you deploy the agent, every run that would have resumed a warm
machine builds a fresh one instead. Deploy it when you are done rotating.
The three ways to apply a secret to a service
Any deployment applies the current values, so pick whichever you already have to hand. None of them needs you to change the code.
| Path | Use it when |
|---|---|
| Redeploy in the dashboard, on the deployments page | You are already in the dashboard, or the code is not on the machine you are at |
afy redeploy <agent> | You are in a terminal but do not have the source checked out |
afy deploy | You have the source and are shipping a code change anyway |
git push to a linked repository | The agent is linked to GitHub and a push already deploys it |
Redeploy and afy redeploy rebuild the running version from the source
Aetherfy already stored, so they apply secrets without changing your code.
afy rollback does not — it re-deploys an image that was already built, and
that image carries the secrets from when it was deployed.
So after rotating a credential for a long-lived service agent:
afy secrets set my-agent API_KEY=sk-new-value
afy redeploy my-agentWithout that second command the agent keeps presenting the old credential until something else redeploys it.
Reading a secret from your Aetherfy agent code
Secrets arrive as ordinary environment variables, so read them with the standard facility for your runtime.
Python:
import os
import sys
api_key = os.environ.get("API_KEY")
if not api_key:
print("API_KEY is not set on this agent", file=sys.stderr, flush=True)
sys.exit(1)
print("API_KEY is present", flush=True)Node:
const apiKey = process.env.API_KEY;
if (!apiKey) {
console.error('API_KEY is not set on this agent');
process.exit(1);
}
console.log('API_KEY is present');Never print a secret’s value. Everything written to stdout and stderr becomes
the agent’s logs on Aetherfy, and those logs are readable with afy logs for
7 days — see /agents/runs-and-logs. Log the presence of
a secret, as above, never its contents.