Config versioning and secrets
🔵 The config/ tree can be kept as a git repository: any config change
made through the host (builder, module toggles, provider, secrets)
becomes a version — it is visible in history, can be compared and rolled back. Secrets
are stored in the same repository, but in encrypted form.
File access and git remain on the host behind the sensitive port
agent_os.Versioning; the HTTP and UI surface is provided by the feature module versioning.
44.1 Model: checkpoint, seal, auto-seal
Recording happens on two levels, so that history is both reliable and meaningful:
| Level | Who does it | What it is |
|---|---|---|
| checkpoint | automatically, the host | a mechanical commit after every config change. Repeated checkpoints are squashed into a single commit (--amend) until the next seal. |
| seal | admin/agent | a single commit with a meaningful message, squashing all checkpoints since the last seal (git reset --soft). |
| auto-seal | the host | seal on idle, if autoseal_idle_secs is set. |
Each commit carries machine trailers Agent / Session / Source; the body
of the message is human-readable:
Add currency tool to felix
Agent: admin
Session: 4f2a9c…
Source: tool:config_commit
checkpoints are needed only for safety between seal; in the final history
after a seal, one commit remains per semantic edit.
44.2 Enabling
# config/server.yaml
versioning:
enabled: true # по умолчанию выключено
branch: config # ветка записи (для git-источника — ветка из --config-ref)
remote: origin # опционально, для push
push: false # push после seal
autoseal_idle_secs: 300
secrets:
mode: mixed # sealed | mixed | plaintext
key_file: ~/.agent-os/config.key
The versioning module must be enabled (id versioning in
config/modules.enabled or server.yaml → modules.enabled). On first start
with enabled: true, a repository is created in the config root (.git, .gitignore) and
the first commit Initial config version.
44.3 Git source (--config-repo)
When the config is cloned from git (see Server configuration), versioning works on top of that clone:
- the clone is full (not shallow) and is on a local branch (
--config-ref), not in detached HEAD — otherwise you cannot commit and push; - the config poller does
merge --ff-only, and on divergence —rebase, that is, local commits are not overwritten; the conflict is simply logged; - after an external update, the baseline seal is re-bound so that
sealdoes not squash someone else's commits; push: truepushes the branch toremoteafterseal(remote access is required).
git -c user.name/email for commits is set locally (Agent OS <agent-os@localhost>), core.autocrlf=false — config files byte-for-byte.
44.4 Secrets
Secrets are stored in config/secrets.yaml as { enc: … } / { plain: … } nodes:
scopes:
global:
OPENAI_API_KEY: { enc: "v1:…" } # зашифровано (AES-256-GCM)
admin:
region: { plain: "eu" } # открытый текст (если политика разрешает)
- Encryption: symmetric AES-256-GCM, nonce per value; decryption only in memory. On disk and in git — ciphertext.
- Key:
AGENT_OS_CONFIG_KEY(base64 or hex, 32 bytes) or the fileversioning.secrets.key_file(by default~/.agent-os/config.key, created on the first sealed value). The key is not versioned. modepolicy:sealed— only{ enc: … }, plaintext is rejected;mixed— per value (default);plaintext— without a key (dev/CI/single host).
- Values are never exposed outward:
list_secretsreturns only scope/key/mode.
Exceptions to versioning: .env and env.overrides.yaml (machine-local
state). keys/deploy_key remains a deliberate plaintext exception.
44.5 HTTP API (ACCESS_ADMIN)
| Method | Path | What it does |
|---|---|---|
| GET | /v1/versioning/status |
{ enabled, initialized, branch, head, dirty, remote, push } |
| GET | /v1/versioning/log?path=&limit= |
commit history (newest first) |
| GET | /v1/versioning/diff?from=&to=&path= |
unified diff between revisions |
| GET | /v1/versioning/show?rev=&path= |
file at a revision |
| POST | /v1/versioning/commit |
{ message } — seal |
| POST | /v1/versioning/restore |
{ rev, path? } — rollback |
| POST | /v1/versioning/push |
push to remote |
| GET | /v1/versioning/secrets?scope= |
list of keys (without values) |
| POST | /v1/versioning/secrets |
{ scope?, key, value, mode? } |
restore overwrites the working tree files; live reload picks up
the changes without a restart.
44.6 UI
The /platform/versions page (menu Platform → "Config versions", owner
agent_os_versioning): list of commits, diff of the selected one, manual commit (seal),
restore, push.
44.7 Agent tools
The engineer agent (admin, via tool_call) has access to: config_versions,
config_version_show, config_version_diff, config_version_restore
(confirm!), config_commit, secrets_list, secrets_set.
44.8 Backups
When versioning is enabled, the builder does not write full copies to
config/agents/.backups/ — they are replaced by git history. When disabled — the previous
behavior.