bastion 0.61.0
This commit is contained in:
+8
-3
@@ -19,7 +19,10 @@ it shares with Linux is tested there, but it has not run on that system yet.
|
||||
| MCP tool servers and their problems | tested | built | built |
|
||||
| Changes since your baseline | tested | built | built |
|
||||
| Stop an agent with your code, from the console or `stop` | run | built | built |
|
||||
| An agent in another account asks (Waiting for you) | tested, with two accounts | built | not built (the ask socket is Unix only) |
|
||||
| An agent on the machine asks to stop another, and follows the answer | run ([gate](verification/m1-gate-linux-2026-11-02.md)) | built | not built (the ask socket is Unix only) |
|
||||
| An agent reads the machine: `agents`, `agents show`, `activity`, `doctor`, the `--json` reads | run | built | not built (no ask pipe) |
|
||||
| The owner answers from their own account: `approve`, `deny`, `switch`, the drops | run | built | not built (no ask pipe) |
|
||||
| The installer checks the release's signature | tested | built | not built (`install.ps1` checks the digest only) |
|
||||
| The console from the owner's own account, no sudo | run | built | the tray's approvals window only |
|
||||
| Activity, report | run | built | built |
|
||||
| `uninstall`, keeping the audit log | run | built | built |
|
||||
@@ -46,7 +49,9 @@ a relay image for one behind a home router.
|
||||
|
||||
- The bastion agent (folder search, a separate program) keeps the plain text it
|
||||
extracts from a shared folder's files in `<folder>/.agent`, inside the shared
|
||||
folder, where a sync client can copy it. The bastion never serves that
|
||||
folder. The fix moves it under the bastion's own state.
|
||||
folder, where a sync client can copy it, and two grants over the same
|
||||
folder (from two Hosts, say) share that one `.agent`. The bastion never
|
||||
serves that folder. The fix moves it under the bastion's own state, per
|
||||
pairing and store.
|
||||
- There is no MCP endpoint on the bastion, on purpose. An agent on the machine
|
||||
uses the command line ([for agents](skills/bastion.md)).
|
||||
|
||||
@@ -313,6 +313,7 @@ says so. Those parts are enforced only by the code as written.
|
||||
| | `release_sign_agent_test.go`: `TestAnOlderSignedAgentManifestDoesNotDowngrade` | An older agent version is neither downloaded nor installed. |
|
||||
| | `claims_update_test.go`: `TestADigestMismatchNeverSwapsTheBinary` | A self-update whose download does not match the manifest's SHA-256 (another build's, empty, truncated) leaves the running binary byte-identical with nothing moved aside. |
|
||||
| | `claims_update_forward_test.go`: `TestTheForwardPathInstallsNothingButTheSignedTarget` | With no approval, a signed manifest for a version other than the target, and an unsigned manifest for the target, are never downloaded from; a signed manifest naming the target is. |
|
||||
| | `install_sig_sh_test.go`: `TestInstallShRefusesAReleaseWhoseSignatureDoesNotVerify` | Where the installer's openssl can check Ed25519, a manifest whose signature is another key's, another version's, malformed or missing is refused, and only one signed by a pinned release key passes; CI requires that openssl (`PRIVATAE_REQUIRE_OPENSSL`). |
|
||||
| | not covered by a test | Where the release key is kept; the installer's SHA-256 check. |
|
||||
| No secrets cached for git | `claims_git_test.go`: `TestTheGitHelperFetchesATokenPerAuthAndStoresNothing` | Each auth asks the daemon for a fresh token; store and erase do nothing; nothing is written to the bastion's config. |
|
||||
| | `claims_git_test.go`: `TestNoHelperOnTheMachineStoresTheForgeToken` | A real git reading the forge through the proxy, with git's `store` helper configured before `git-setup`'s lines, after them, or in the repository, authenticates with the host's token and writes it nowhere. |
|
||||
|
||||
+14
-8
@@ -22,11 +22,11 @@
|
||||
| `approvals drop [--host <host> \| --machine] <id>` | Take back an approval this machine issued and has not used yet. |
|
||||
| `grants drop <store id> [--host <host>]` | Remove a folder grant held on this machine. The host is told. |
|
||||
| `device-init` | Make this machine your approval device. |
|
||||
| `device-approvals` | What your machines are asking you to approve, in their words. |
|
||||
| `device-approvals [--json]` | What your machines are asking you to approve, in their words. The words listing records what it showed, which is all `device-approve all` signs; `--json` is for a program and records nothing. |
|
||||
| `device-approve <id>\|all [--code <code>]` / `device-deny <id>` | Approve or refuse from the device. `all` signs only the asks the last listing showed, and never a ship plan that runs root work: that takes `--code`. |
|
||||
| `pin-device <key>` / `unpin-device <key>` | On a machine you govern: accept (or stop accepting) approvals signed by your device. Root required. Prints the `pin-machine` line to run on the device. |
|
||||
| `pin-machine <host> <key>` / `unpin-machine <host>` | On your device: pin (or drop) a machine's key, as that machine printed it, so the device can sign ship plans that include it. |
|
||||
| `ops [--host <host>]` | The ops your host wrote that this machine holds, and the standing op grants. |
|
||||
| `ops [--host <host>] [--json]` | The ops your host wrote that this machine holds, and the standing op grants. |
|
||||
| `ops drop <grant> [--host <host>]` | Take back a standing op grant. The host is told. |
|
||||
| `coders set [--max N] [--mem MB] [--cpus F] [--engines a,b\|all] [--allow-lan host[:port],...] [--image-prefix <registry/path/>\|default]` | Size this machine for coding runs your hosts place here: how many at once, memory and CPUs per run, which engines, LAN hosts a run may reach, and where run images may come from (`<prefix>harness-<engine>@sha256:...`; default `git.privatae.ai/privatae-harness/`). Does not switch them on. |
|
||||
| `coders on` / `coders off` | Allow coding runs here (Linux, bastion running as root), filling unset sizes with defaults; or stop new ones. Off by default. Each run is a container with no network of its own. Through this bastion it reaches the public internet, and never this machine or its LAN unless you named that host with `--allow-lan`. |
|
||||
@@ -46,10 +46,12 @@
|
||||
| `report [--since 7d] [--json] [--out FILE \| --out -]` | Write what this bastion knows as one Markdown file (or JSON): a summary of the problems first, then the agents running now, scheduled jobs that start an agent, MCP tool servers and their problems, changes since the baseline, and the activity in the period. No AI model writes any of it; last prompts and secrets are left out. Default file: `reports/` in the config directory of the account that ran it; `--out -` prints it instead. |
|
||||
| `activity [--since 7d] [--json]` | What happened on this machine, newest first: stops (by you or a Host, and stops refused), your approvals, what each Host did here, Hosts paired or removed, programs marked as yours, capabilities switched off. Read from the records this bastion already keeps. |
|
||||
| `agents [--json] [--prompts]` | Every AI agent on this machine and what it is doing: for Claude Code, the session's name and title, whether it is waiting for you and on what, and its permission mode, read from Claude Code's own session files; for every agent, its folder and git branch, how long it has run, who started it, what it is running now (secrets redacted) and the tool servers it started with itself. Names and titles are what each agent says about itself. `--prompts` adds each session's last prompt. Nothing here is sent to a Host. |
|
||||
| `agents show <session name or pid> [--json] [--prompts]` | One agent with everything the bastion knows about it: the lines `agents` prints, then what it is, its pid and parent, the file the system says it runs, its account, what it runs now, its tool servers and what it says about itself. A session name must match exactly one session. Its command line is in `--json` only, since arguments can carry a key. |
|
||||
| `doctor [--json]` | What is wrong with this install, and the fix for each one: whether the bastion runs, whether a newer version is published, the machine's owner account (installed for the whole machine), its second factor, accounts whose asks are held, each Host pairing, the switch list, and the ops sandbox. Exit status 1 when it finds a problem. A newer version it could not read from privatae.ai is not one. It asks privatae.ai at most once in six hours, the rate the update check keeps, and otherwise uses the last answer. |
|
||||
| `stop <session name or pid> [--wait 5m] [--json]` | Stop an agent this bastion sees, and every process it started, as the machine's owner. At a terminal it asks for your code (`stepup-enroll --machine`); run by an agent, it only files a request that you approve under Waiting for you in the console (or with `approve --machine`). `--wait` follows the request until it is answered, as `request` does. When the bastion is installed for the whole machine and the command runs in another account, it asks over the bastion's local ask socket, which names the asking account (and on Linux the asking agent) from the kernel; one account may have five requests waiting. The running bastion carries it out within two minutes of the approval or not at all, and never stops an app you are using, the bastion itself, or a process the scan does not see as an agent. |
|
||||
| `request <id> [--wait 5m] [--json]` | Where an ask stands, for the account that asked it: `waiting`, `approved` (being carried out), `stopped`, `not_stopped` (with the reason), `denied`, or `unknown` (no such ask from this account, or older than a day). Exit status 0 for stopped, 1 for not, 3 when still waiting after `--wait`. Another account's requests read as unknown. Every ask, approval, denial and stop is recorded with the asking account, the asking agent and the target, each with how it was started. |
|
||||
| `help` | Print every command. |
|
||||
| `switch <host> <family> on\|off` / `switch --list` / `switch --reset` | Switch a capability family off for one host on this machine, or back on; `--list` shows every host's families. If the list of switched-off families cannot be read, every family is refused to every host until `--reset` sets the unreadable file aside (kept, not deleted). Switching and resetting need root. |
|
||||
| `switch <host> <family> on\|off` / `switch --list [--json]` / `switch --reset` | Switch a capability family off for one host on this machine, or back on; `--list` shows every host's families. If the list of switched-off families cannot be read, every family is refused to every host until `--reset` sets the unreadable file aside (kept, not deleted). Switching and resetting need root, except from the machine's owner account beside a whole-machine install, which switches through the bastion's ask socket as the console does: off with nothing, on with the owner's code ([Acts from the owner's account](#acts-from-the-owners-account)). |
|
||||
| `approvals-owner --sid <SID> [--replace]` | Windows, beside the system service: name the one account whose tray icon may list and answer approvals. Administrator only. |
|
||||
| `approvals-owner --account <name> [--replace]` | Linux and macOS, beside the system service: name the machine's owner account, whose `ui` opens a limited console session without sudo. The installer records the account that ran it through sudo. Another account takes it over only with `--replace`, typed at a terminal. Administrator only. |
|
||||
| `tray` | Windows, beside the system service: your icon and approvals window, started at every sign-in. |
|
||||
@@ -62,19 +64,23 @@
|
||||
| `baseline diff [--json]` | What is running that the baseline does not hold. Administrator only, or the owner's account through the bastion installed for the whole machine. |
|
||||
| `observe:baseline [--force]`, `observe:baseline:show`, `observe:delta [--json]` | The same as `baseline record`, `baseline show` and `baseline diff`, under their old names. |
|
||||
| `backup key init [--replace] [--label <name>]` | Make this bastion's backup key and print the fields to register on your host. `--replace` keeps the old key. |
|
||||
| `backup key show` | The backup key this bastion holds, and the older ones it keeps. |
|
||||
| `backup requests [--host <host>]` | Restore requests your host sent this machine. |
|
||||
| `backup key show [--json]` | The backup key this bastion holds, and the older ones it keeps. The secret half never leaves its file. |
|
||||
| `backup requests [--host <host>] [--json]` | Restore requests your host sent this machine. `--json` leaves out the sealed keys a request carries (the one the host sent, and the one resealed for it) and keeps the digest of the one the host sent. |
|
||||
| `backup approve [--host <host>] <id>` / `backup deny …` | Answer one: approving seals that one backup's key to the requesting host. |
|
||||
| `backup reseal --sidecar <file> --to <host key>` | Seal one backup's key to a host's own key, offline. |
|
||||
| `backup restore-plan --dir <folder> [--stamp <stamp> --to <host key>]` | List the backups in a folder; reseal one for the host that replaces a lost one. |
|
||||
| `backup share --with <host> (--from <host> \| --dir <folder>)` | Let a paired host list and ask for the backups in another host's folder (or any folder). |
|
||||
| `backup shares --with <host>` / `backup unshare --with <host> <name>` | The folders shared with a host; take one back. |
|
||||
| `backup shares --with <host> [--json]` / `backup unshare --with <host> <name>` | The folders shared with a host; take one back. |
|
||||
| `version` | Print the version. |
|
||||
|
||||
Run `privatae-bastion` with no arguments for the built-in help.
|
||||
|
||||
## Reads from the owner's account
|
||||
|
||||
Installed for the whole machine, the bastion runs as root and keeps its records in root's state. On Linux and macOS, the account recorded as the machine's owner (`approvals-owner --account`, which the installer writes) reads them without sudo: `status`, `agents`, `schedules`, `tool-servers`, `posture`, `baseline show`, `baseline diff`, `activity`, `report` and `approvals` ask the running bastion over its local ask socket, which knows from the kernel which account is asking, and print what it answers. That is what the console already shows the owner, so an agent the owner runs can read it too; `posture`, which the console has no page for, adds the firewall checks, read by the bastion as the administrator. No read prints the delegation tag an agent carries, as the console never shows one. Nothing that changes anything goes this way; those still take the owner's code.
|
||||
Installed for the whole machine, the bastion runs as root and keeps its records in root's state. On Linux and macOS, the account recorded as the machine's owner (`approvals-owner --account`, which the installer writes) reads them without sudo: `status`, `agents` (and `agents show`), `schedules`, `tool-servers`, `posture`, `baseline show`, `baseline diff`, `activity`, `report`, `approvals`, `switch --list`, `ops`, `device-approvals`, `backup key show`, `backup requests`, `backup shares` and `doctor` ask the running bastion over its local ask socket, which knows from the kernel which account is asking, and print what it answers. That is what the console already shows the owner, so an agent the owner runs can read it too, and more that the console has no page for, all of it about the owner's own machine: `posture` adds the firewall checks, read by the bastion as the administrator; `ops` and the backup reads show what each Host holds here; `doctor` checks the install. Read this way, `device-approvals` records nothing as shown, and says that the asks are answered as the administrator. No read prints the delegation tag an agent carries, as the console never shows one. The few acts that go this way follow the console's rules for them ([Acts from the owner's account](#acts-from-the-owners-account)): what widens reach takes the owner's code.
|
||||
|
||||
Any other account is refused. `agents`, `schedules`, `tool-servers` and `posture` then show what that account can read itself, and say so; the rest print the refusal and the administrator's command. Comparing against the baseline, the posture checks and the report are reused for 30 seconds, and the bastion answers four reads at a time, so a polling agent cannot slow the machine.
|
||||
Any other account is refused. `agents`, `schedules`, `tool-servers` and `posture` then show what that account can read itself, and say so; the rest print the refusal and the administrator's command. Comparing against the baseline, the posture checks, the report and `doctor` are reused for 30 seconds, and the bastion answers four reads at a time, so a polling agent cannot slow the machine.
|
||||
|
||||
## Acts from the owner's account
|
||||
|
||||
The same account acts on the machine's bastion through the same socket, with the rules the console uses for it: `approve` (the machine's own asks with `--machine`, or a Host's) shows the request, takes the code from the owner's authenticator at the terminal, and asks the bastion to approve it, where wrong codes are counted and lock as the console's do; `switch <host> <family> on` takes the owner's code too. `deny`, `switch … off`, `approvals drop`, `grants drop`, `ops drop` and `device-deny` take nothing, since they only take reach away. Each act is a line in the machine's audit log naming the account. Any other account is refused, with the administrator's command. On Windows these still run from an Administrator terminal, and an ordinary account is told so. `device-approve` stays the administrator's on every system, as the console keeps it.
|
||||
|
||||
@@ -257,8 +257,10 @@
|
||||
agent download is checked the same way, and an installed agent is never
|
||||
replaced with an older one. The release key never reaches the machine that
|
||||
builds and publishes: each release waits until the key holder signs it on
|
||||
their own computer. The installer checks the SHA-256; see
|
||||
[SECURITY.md](../SECURITY.md) for what that does and does not prove.
|
||||
their own computer. The installer checks the SHA-256, and `install.sh`
|
||||
also checks the manifest's signature against the same pinned keys where the
|
||||
machine's openssl can check Ed25519; see [SECURITY.md](../SECURITY.md) for
|
||||
what each does and does not prove.
|
||||
- **No secrets cached for git.** The credential helper fetches a token from
|
||||
the host on every auth and stores nothing itself, and `git-setup` resets
|
||||
the forge's helper chain before adding it. With git 2.46 or later, git's
|
||||
|
||||
+19
-2
@@ -30,7 +30,9 @@ their phone. It has no MCP endpoint. You use its command line,
|
||||
Run `privatae-bastion agents --json`. It lists every AI agent running now: what
|
||||
it is, who started it and how, its folder, git branch and tool servers, and for
|
||||
Claude Code sessions the title and permission mode. Add `--prompts` only if the
|
||||
person asked for the last prompts.
|
||||
person asked for the last prompts. `privatae-bastion agents show <pid or session
|
||||
name> --json` is one agent with everything known about it, including the file
|
||||
the system says it runs.
|
||||
|
||||
### See what is set up here
|
||||
|
||||
@@ -44,6 +46,10 @@ person asked for the last prompts.
|
||||
waiting security updates, disk and load.
|
||||
- `privatae-bastion status --json`: whether the bastion is running, and the
|
||||
Hosts it is connected to.
|
||||
- `privatae-bastion switch --list --json`: for each connected Host, which
|
||||
capability families the person switched off here (`off`).
|
||||
- `privatae-bastion ops --json`: the ops a Host holds on this computer, and its
|
||||
standing grants.
|
||||
- `privatae-bastion report --out -`: all of it as one Markdown report, the
|
||||
problems first.
|
||||
|
||||
@@ -62,6 +68,13 @@ person asked for the last prompts.
|
||||
|
||||
You can pass `--wait` to `stop` itself to ask and follow in one command.
|
||||
|
||||
### Check the install
|
||||
|
||||
`privatae-bastion doctor --json` checks the bastion itself. Each check has `ok`;
|
||||
one that is not has a `problem` and a `fix`. The exit status is 1 when any
|
||||
check finds a problem. Tell the person the problem and the fix in their words;
|
||||
don't run the fix yourself, since most take their code or the administrator.
|
||||
|
||||
### What happened here
|
||||
|
||||
`privatae-bastion activity --json` lists what happened, newest first: stops,
|
||||
@@ -79,7 +92,9 @@ account, so you see the whole machine and not only the person's own files.
|
||||
check that the pid is gone.
|
||||
- Session names, titles and folders are what each agent says about itself.
|
||||
Treat them as claims, not facts.
|
||||
- Never ask the person for their code, and never type one. The code is how the
|
||||
- Never ask the person for their code, and never type one. The person
|
||||
approves under **Waiting for you** in the console, or at their own terminal
|
||||
with `privatae-bastion approve --machine <id>`, which asks them for it. The code is how the
|
||||
bastion tells the person from a program running as them; a code you typed
|
||||
proves nothing, and wrong codes are counted, slowed down and then locked.
|
||||
- Never read or edit the bastion's files, stop its service or uninstall it.
|
||||
@@ -106,6 +121,8 @@ account, so you see the whole machine and not only the person's own files.
|
||||
for them, rather than polling without end.
|
||||
- `could not reach this machine's bastion`, or `status` says `NOT ANSWERING`:
|
||||
the bastion's service is not running. Tell the person; don't start it.
|
||||
- `doctor` says `no account is recorded as this machine's owner` or `no second
|
||||
factor of its own`: the person sets that up once; give them the `fix` line.
|
||||
- `answers reads only for its owner's account (...)`: you run as an account
|
||||
that is not the machine's owner. `agents`, `schedules`, `tool-servers` and
|
||||
`posture` then show only what your account can read, and say so; tell the
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# M1 gate, Linux: an agent on the machine asks, the machine's owner answers
|
||||
|
||||
Run 2026-11-02 on the Ubuntu 24.04 virtual machine the [M0 gate](m0-gate-linux-2026-10-31.md)
|
||||
used (qemu, user-mode networking), with no Host anywhere. The bastion is
|
||||
installed for the whole machine (its systemd unit, running as root), and
|
||||
`tester` is recorded as the machine's owner. `other` is a second account with
|
||||
no sudo. The binary was built from the 0.61.0 release branch just before this
|
||||
record was added (`privatae-bastion version`: `0.61.0+090bdb8`) and put in
|
||||
place of the installed one.
|
||||
|
||||
The asker is an AI agent the bastion recognises: a program at
|
||||
`~/.local/bin/claude`, which it lists as Claude Code, started from a remote
|
||||
login (ssh). The target is `aider`, started every minute by a cron job in
|
||||
`tester`'s crontab. Both are stand-ins (`sh` and `sleep` under those names),
|
||||
which is how the bastion meets them anyway: by the program a process runs and
|
||||
how it was started.
|
||||
|
||||
macOS and Windows have not been run. On Windows an agent cannot ask yet,
|
||||
because the ask socket is Unix only ([STATUS](../STATUS.md)).
|
||||
|
||||
| Gate step | Result |
|
||||
|---|---|
|
||||
| The agent lists the AI agents on the machine (`agents --json`) | `aider` (started by a scheduled job) and Claude Code (started from a remote login), with pids and accounts |
|
||||
| The agent asks to stop `aider` (`stop <pid> --json`) | A request id and state `waiting`; the request names the agent that asked and the target |
|
||||
| The owner lists what waits, from their own account (`approvals --machine`) | The request, in the same words |
|
||||
| The owner approves with a wrong code | Refused; nothing stopped |
|
||||
| The owner approves with the code from their authenticator (`approve --machine <id>`) | Approved, and the bastion carried it out |
|
||||
| The agent follows its request (`request <id> --wait 30s --json`) | State `stopped`, outcome "You stopped aider"; the process is gone |
|
||||
| The agent asks to stop the next cron'd `aider`; the owner denies it (`deny --machine <id>`, no code) | Denied; the agent's `request` reads `denied` with exit status 1; `aider` keeps running |
|
||||
| The agent asks the same stop again | Refused: the owner refused this same stop within the last 24 hours |
|
||||
| `other` tries `approvals --machine`, `approve`, `deny`, `doctor` | Each refused, naming the owner's account, with the administrator's command as typed (`sudo -H privatae-bastion approve --machine <id>`); the request stays waiting |
|
||||
| `other` reads `agents --json` | Told the machine's bastion answers only its owner, and shown what that account can read itself |
|
||||
| `other` asks after the agent's request (`request <id>`) | `unknown`: no such request was asked from that account |
|
||||
| The machine's audit log | Each ask, approval and denial names the asking account, the asking agent (Claude Code, remote login) and the target (aider, scheduled job); each act from the owner's account is its own line naming that account |
|
||||
|
||||
Found and fixed while running M1 on this machine, before this record:
|
||||
`switch --list` was refused by the M0 guard meant for `switch`; a read the
|
||||
bastion answered but could not build came back as a refusal with the
|
||||
administrator's command; "not paired" named `pair` without `sudo -H`; an act
|
||||
refused for another account said "reads" and gave a bare `deny`; and
|
||||
`approve` and `approvals --machine` from another account were refused as a
|
||||
read and without `--machine`.
|
||||
|
||||
## Transcript (abridged)
|
||||
|
||||
```
|
||||
$ ~/.local/bin/claude -c 'privatae-bastion agents --json' # summarised
|
||||
aider pid 5162 origin scheduler user tester
|
||||
claude-code pid 5265 origin remote user tester
|
||||
|
||||
$ ~/.local/bin/claude -c 'privatae-bastion stop 5162 --json'
|
||||
{
|
||||
"request": "857285ef",
|
||||
"state": "waiting",
|
||||
"text": "Stop aider in /home/tester (pid 5162) on this machine, and every process it started. Asked from Claude Code (pid 5324), running as tester.",
|
||||
"asked_as": "tester"
|
||||
}
|
||||
|
||||
$ privatae-bastion approvals --machine
|
||||
[857285ef] asked 2026-11-02T05:23:07Z
|
||||
Stop aider in /home/tester (pid 5162) on this machine, and every process it started. Asked from Claude Code (pid 5324), running as tester.
|
||||
|
||||
$ privatae-bastion approve --machine 857285ef # a wrong code
|
||||
Approve this? Enter the code from your authenticator (or leave empty to cancel): error: code refused
|
||||
$ privatae-bastion approve --machine 857285ef
|
||||
Approve this? Enter the code from your authenticator (or leave empty to cancel): approved.
|
||||
|
||||
$ ~/.local/bin/claude -c 'privatae-bastion request 857285ef --wait 30s --json'
|
||||
{
|
||||
"request": "857285ef",
|
||||
"state": "stopped",
|
||||
"outcome": "You stopped aider (pid 5162) running on this machine.",
|
||||
...
|
||||
}
|
||||
|
||||
$ ~/.local/bin/claude -c 'privatae-bastion stop 6145 --json' # the next cron'd aider
|
||||
"request": "f090208b", "state": "waiting"
|
||||
|
||||
other$ privatae-bastion approve --machine f090208b
|
||||
error: this machine's bastion acts only for its owner's account (tester), not other
|
||||
As the administrator: sudo -H privatae-bastion approve --machine f090208b
|
||||
other$ privatae-bastion approvals --machine
|
||||
error: this machine's bastion answers reads only for its owner's account (tester), not other
|
||||
As the administrator: sudo -H privatae-bastion approvals --machine
|
||||
|
||||
$ privatae-bastion deny --machine f090208b
|
||||
denied.
|
||||
$ ~/.local/bin/claude -c 'privatae-bastion request f090208b --json'
|
||||
"state": "denied" (exit status 1)
|
||||
$ ~/.local/bin/claude -c 'privatae-bastion stop 6145 --json'
|
||||
"why": "the machine's owner refused this same stop within the last 24 hours, so it cannot be asked again yet"
|
||||
|
||||
# the machine's audit log (machine-factor/audit.jsonl), summarised
|
||||
05:23:07Z local_stop_ask asked to stop aider (pid 5162) asker: tester, claude-code, remote target: aider, scheduler
|
||||
05:23:08Z stepup_approve approved: local_stop|5162|aider asker: tester, claude-code, remote target: aider, scheduler
|
||||
05:23:08Z owner_lane_act approve the machine's request 857285ef…, from the owner's account tester through its ask socket
|
||||
05:24:04Z local_stop_ask asked to stop aider (pid 6145) asker: tester, claude-code, remote target: aider, scheduler
|
||||
05:24:06Z stepup_deny denied: local_stop|6145|aider asker: tester, claude-code, remote target: aider, scheduler
|
||||
05:24:06Z owner_lane_act deny the machine's request f090208b…, from the owner's account tester through its ask socket
|
||||
```
|
||||
Reference in New Issue
Block a user