Skip to content
Cockpit0.29.0
A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live

project.ssh-key-access-is-preauthorized@1

Owner-authorized SSH access persists across clients

What it is

URI
majordomus://rule/project.ssh-key-access-is-preauthorized@1
Kind
rule
Identity
project.ssh-key-access-is-preauthorized@1
Path
.ai/repo/rules/project/ssh-key-access-is-preauthorized.v1.md
Provenance
declared
Media type
text/markdown
As a capability
rule.project.ssh-key-access-is-preauthorized@1

Front matter

{
  "id": "project.ssh-key-access-is-preauthorized",
  "version": 1,
  "kind": "rule",
  "title": "Owner-authorized SSH access persists across clients",
  "description": "Preserve the owner's explicit authorization for SSH with existing keys to any host in each native client configuration.",
  "statement": "Workers may use existing SSH keys to connect to any host and run the remote commands their task requires without asking for SSH authorization again; native client settings must preserve this authorization.",
  "status": "active",
  "class": "blocking",
  "depends_on": [],
  "tags": [
    "providers",
    "authorization",
    "ssh"
  ],
  "x-majordomus": {
    "tests": [
      "test/cases/304_a_provider_is_declared_once.sh"
    ]
  }
}

Content

---
id: project.ssh-key-access-is-preauthorized
version: 1
kind: rule
title: Owner-authorized SSH access persists across clients
description: Preserve the owner's explicit authorization for SSH with existing keys to any host in each native client configuration.
statement: Workers may use existing SSH keys to connect to any host and run the remote commands their task requires without asking for SSH authorization again; native client settings must preserve this authorization.
status: active
class: blocking
depends_on: []
tags: [providers, authorization, ssh]
x-majordomus:
  tests: [test/cases/304_a_provider_is_declared_once.sh]
---

# Authorization

On 2026-10-10 the repository owner explicitly authorized persistent SSH access to any
host using existing keys, including arbitrary commands on those hosts, and requested
the same permission for every client through this shared layer. This is standing SSH
authorization for work the owner requests, not a new task or permission to undertake
unrelated work. Do not ask for the same SSH authorization again.

Use public-key authentication, either an existing SSH configuration/agent identity or
an explicit `-i` identity. Prefer `-o BatchMode=yes -o PreferredAuthentications=publickey`.
The cluster identity is `~/.ssh/cluster_ed25519` where installed; existing host aliases
may select another key. Never print or copy private-key material. Keep SSH host-key
verification enabled. This rule does not override an administrator's policy or grant
access a remote account does not have.

# Canonical command prefixes

The gate reads this block; client-specific syntax is derived from it. Both executable
spellings are included so invoking the system binary has the same permission as PATH
lookup. Hosts, accounts, key paths and remote commands are unrestricted by the native
prefix permission. Authentication remains SSH's responsibility; a prefix rule cannot
itself enforce which authentication method SSH negotiates.

```json ssh-permissions
{"commands": ["ssh", "/usr/bin/ssh"]}
```

# Projection and enforcement

`scripts/ci/providers-check --sync-permissions` merges the required permissions into
the native JSON settings and regenerates the dedicated Codex rules file. It preserves
unrelated hooks, MCP connections and settings. `--permissions-only` checks those
projections without changing them and exits 10 on a missing, invalid or stale one.
The ordinary providers gate checks them too whenever this rule exists.

The policy's `ssh-permissions-on-commit` enforcement entry wires that check into
`.githooks/pre-commit`; `doctor` checks the hook wiring. Case 304 removes permissions
and corrupts their source to prove refusal, then proves synchronization and idempotence.

Claude Code consumes `.claude/settings.json` `permissions.allow`. Codex consumes
`.codex/rules/ssh.rules` when the project is trusted. Gemini CLI consumes
`.gemini/settings.json` `tools.allowed`; this avoids relying on its currently disabled
workspace policy directory. Clients without a native adapter follow this rule through
their shared instructions; no native enforcement is claimed for them. The provider
inventory is [the generated provider document](../../../../docs/generated/providers.md).

The owner's user-level settings also carry these permissions so they apply outside this
checkout. Those machine-local settings are not committed or silently rewritten by a
repository check. Restart clients that load settings only at startup. More restrictive
managed policies still take precedence.

Native formats verified on 2026-10-10 against the vendors' own pages: Codex rules at
`https://learn.chatgpt.com/docs/agent-configuration/rules`, Claude permissions at
`https://code.claude.com/docs/en/permissions` and Gemini configuration at
`https://geminicli.com/docs/reference/configuration/`.