3.0.0-beta.41). Features may change before the next stable release.Switch to stable →secrets
ak secrets run
Run one program with secrets delivered only in named environment variables, under exec grants.
Use ak secrets run to start one program with secrets in the environment
variables --env names, and nowhere else. It serves a coding agent: the
caller is identified the way ak secrets resolve identifies it, by walking the
process tree and hashing the agent's binary.
Usage
ak secrets run --env VAR=REF [--env VAR=REF ...] [--purpose <text>] [--project <slot>] [--session <id>] -- <program> [args...]The program and its arguments come after --; everything after the separator
belongs to the program, never to ak. At least one --env pair is required,
at most 16 are accepted, and no variable may be named twice. --json is not
supported: the program's own output is the output.
| Flag | Default | Description |
|---|---|---|
--env VAR=REF | required | Deliver secret REF in environment variable VAR. Repeatable. |
--purpose <text> | empty | Purpose label the grant must match literally. |
--project <slot> | the AK project containing the current directory | Project slot the grants are scoped to. |
--session <id> | none | Session id tying this run to the agent run that asked for it. |
--backend <backend> | keychain | Backend that holds the values: keychain, file or memory. |
--unlock-with-recovery | off | Open the file backend's vault with a recovery private key and set a new passphrase. |
Exec grants
Each VAR=REF pair needs an exec grant
(ak secrets grant REF --exec PROGRAM --env VAR) for the calling agent on
exactly this program: its path with every symlink resolved and its content
hash. A program found elsewhere on PATH, or changed since the grant, matches
no grant, and each uncovered scope is filed for the operator to answer with
ak secrets approve, as resolve files one. An ordinary grant never
releases here, and an exec grant never releases to resolve.
A REF with no stored value that names an alias follows it
one hop, and the exec grant is checked against the alias's target, never the
alias name.
Every scope is checked, and the program re-hashed, before any value is read, so a run a grant check refuses spends no allow-once. If the program still cannot start after its values were released, the ledger records that it never started.
How the program runs
- No shell. The program is started directly, in the current working directory, so nothing in its arguments is expanded. Shells and launchers are refused.
- A rebuilt environment. A few variables are copied from this one (
HOME,USER,LANG,TERM,TMPDIRand their kind),PATHis a fixed list of the system directories (led, for a#!/usr/bin/env NAMEscript, by the directoryNAMEwas found in), and the granted variables are added; nothing else, proxies and runtime options included. A program that runs a helper installed outside the system directories must name it by path. - Struck output. The program's output is relayed with every granted value struck out. The last few bytes are held back (fewer than the longest form of a value, which for an escaped form can exceed the value) until the program writes more or exits. Its output goes to pipes, not a terminal.
- Signals and exit. Ctrl-C reaches the program from the terminal, and
SIGTERM and SIGHUP are passed on to it;
akwaits for it to exit and never kills it. The program's exit status is this command's.ak's own failures always print an error startingsecrets run:on stderr; the program's status is passed on with nothing added, though the program itself can print anything.
An exec grant bounds which program gets a value, not what the program does with
it. The program can still send it anywhere, write it to a file or pass it to a
child of its own; an interpreter runs whatever script it is given; a program
such as curl, wget or gh can be told by its arguments to send a variable
anywhere or to run another program; and any process of the same user can read
the program's environment while it runs. Grant exec scopes to programs you
would hand the value to yourself.
The command reads the vault, the alias file and the grant file, writes one audit row per variable, and starts the program. It never prints a value.
Output
There is no ak output of its own on success: stdout and stderr carry the
program's relayed output, with granted values struck out.
Exit behavior
| Exit | Meaning |
|---|---|
0 | The program exited 0. Any other status it exits with is passed on (128 plus the signal number if a signal ended it). |
2 | Invalid flags, --json, no program after --, or a refused program or variable. |
3 | No secret by that ref. |
5 | The vault, alias file, grant file or audit ledger could not be used, or the program could not start. |
6 | A block refuses the caller, its identity cannot be named, or the program changed after it was checked. |
7 | The file backend's vault needs a passphrase and this run has no terminal. |
8 | No exec grant covers a variable; a request is waiting for ak secrets approve. |
9 | The caller raised too many approval requests and is in its cool-down. |
15 | A synced vault policy refuses this release, or whether one governs it cannot be answered; the JSON error's sync.reason names why. |