Guides
Rotate secrets in Hives
Hives keeps a project's secrets encrypted and versioned. In this guide you load a set of secrets in one call, rotate one, confirm its version moved, read the new value back once and retire it.
You need an API key with hives:read and hives:write.
export GENESIS_API_KEY="sk_..."
export GENESIS_BASE_URL="https://os.one.ml/api"1. Create a project
Secrets belong to a Hives project. The name carries a timestamp, because a deleted project keeps its name while it finishes deleting.
PROJECT_ID=$(curl -sf -X POST "$GENESIS_BASE_URL/v1/hives/projects" \
-H "Authorization: Bearer $GENESIS_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"name\": \"secrets-$(date +%s)\", \"kind\": \"function\"}" | jq -er .id)
echo "$PROJECT_ID"2. Load secrets in one call
The bulk call takes an array and creates or updates each secret by name: a new name starts at version 1, an existing one moves to its next version. Names start with a letter and use letters, digits and _; values are up to 65,536 bytes.
curl -sf -X PUT "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID/secrets/bulk" \
-H "Authorization: Bearer $GENESIS_API_KEY" \
-H "Content-Type: application/json" \
-d '[
{"name": "DATABASE_URL", "value": "postgres://db1.internal/app"},
{"name": "WEBHOOK_SIGNING_SECRET", "value": "whsec_example", "description": "Signs outgoing webhooks"}
]'{
"secrets": [
{ "id": "sec_395aeb935d2642cf92d64e82933bec9a", "name": "DATABASE_URL", "description": null, "version": 1,
"created_at": "2026-10-20T07:52:51.765251Z", "updated_at": "2026-10-20T07:52:51.765251Z" },
{ "id": "sec_d591e78ac5714ee9a9b30e05796c4ca9", "name": "WEBHOOK_SIGNING_SECRET", "description": "Signs outgoing webhooks", "version": 1,
"created_at": "2026-10-20T07:52:51.844258Z", "updated_at": "2026-10-20T07:52:51.844258Z" }
],
"success": true
}Responses carry names and versions, never values. Operation: hives_bulk_upsert_secrets.
3. Rotate one secret
Find the secret's ID by name, then replace its value. The answer shows the new version.
SECRET_ID=$(curl -sf "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID/secrets" \
-H "Authorization: Bearer $GENESIS_API_KEY" | jq -r '.data[] | select(.name == "DATABASE_URL") | .id')
curl -sf -X PUT "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID/secrets/$SECRET_ID" \
-H "Authorization: Bearer $GENESIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"value": "postgres://db2.internal/app"}'{ "id": "sec_395aeb935d2642cf92d64e82933bec9a", "name": "DATABASE_URL", "description": null, "version": 2,
"created_at": "2026-10-20T07:52:51.765251Z", "updated_at": "2026-10-20T07:52:53.014391Z" }Operations: hives_list_secrets, hives_update_secret.
4. Confirm the version and read the value
Reading the secret returns its metadata. Revealing returns the current value; use it only where the value is needed.
curl -sf "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID/secrets/$SECRET_ID" \
-H "Authorization: Bearer $GENESIS_API_KEY" | jq '{name, version}'
curl -sf "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID/secrets/$SECRET_ID/reveal" \
-H "Authorization: Bearer $GENESIS_API_KEY"{ "name": "DATABASE_URL", "version": 2 }
{ "value": "postgres://db2.internal/app" }Operations: hives_get_secret, hives_reveal_secret.
5. Retire a secret and clean up
curl -sf -X DELETE "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID/secrets/$SECRET_ID" \
-H "Authorization: Bearer $GENESIS_API_KEY"
curl -sf -X DELETE "$GENESIS_BASE_URL/v1/hives/projects/$PROJECT_ID" \
-H "Authorization: Bearer $GENESIS_API_KEY"Operations: hives_delete_secret, hives_delete_project.
Next
- Rotate on a schedule from CI: give the job its own key with only
hives:writeand the bulk call from step 2. - Every secret operation: Hives API.
- Scopes and least privilege: Scopes.
One Superintelligence, Inc. · Built from Genesis 0.1.13 and the live gateway on 2026-10-20. Support