Ctrl K
ComunidadGuías…

docs/implementation-runbook.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Implementation runbook

> Historical build path. The broad Scoped runtime, durable state/jobs, integrated OAuth and optional elevation code now exist. Use this document to understand implementation sequencing, not as the current project status. Current status lives in [project-status.md](project-status.md); current productization work must not reopen completed gates without concrete evidence.

This is the detailed build path that guided implementation. The canonical architecture is docs/architecture.md and the gate sequence is docs/mvp-first.md.

## 0. Ground rules

Before code:

1. read docs/README.md
2. complete Gate -1
3. complete Gate 0A
4. do not build beyond the current gate
5. use Go for both reference binaries
6. keep Gateway unprivileged and Broker local-only

## 1. Repository layout

Reference layout:

~~~text
cmd/
  vps-agent-gateway/
  vps-agent-broker/

internal/
  gateway/
    mcp/
    auth/
    tools/
    brokerclient/
  broker/
    api/
    authz/
    policy/
    files/
    systemd/
    docker/
    exec/
    jobs/
    state/
    secrets/
    audit/
  shared/
    protocol/
    errors/

policy/
  schema.json
  controlled.yaml
  scoped.example.yaml
  full.example.yaml

deploy/
  systemd/
  reverse-proxy/

tests/
  integration/
  security/
~~~

Runtime:

~~~text
/etc/vps-agent/       config/secrets metadata
/run/vps-agent/       broker.sock
/var/lib/vps-agent/   state/jobs/audit
~~~

## 2. Gate 0B implementation

Build only vps-agent-gateway.

Use the official MCP Go SDK and Streamable HTTP.

Tools:

~~~text
system.info
file.read_test
file.write_test
~~~

Filesystem root:

~~~text
/tmp/vps-agent-poc/
~~~

Requirements:

- non-root service account
- no Docker socket
- no SQLite
- no generic shell
- input schemas
- output size limits
- path confinement tests
- MCP Inspector test

Use an internal Executor interface so Gate 0B's local test executor can later be replaced by BrokerClient without rewriting tool handlers.

## 3. Gate 1 Broker

Add vps-agent-broker.

### IPC

Use a Unix Domain Socket.

Recommended:

~~~text
/run/vps-agent/
  owner: root
  group: vps-agent
  mode: 0750

/run/vps-agent/broker.sock
  owner: root
  group: vps-agent
  mode: 0660
~~~

Check peer credentials where practical.

### First Broker operations

~~~text
ping
system.info
service.status
service.restart
~~~

Allow only one explicitly configured non-critical unit.

Broker authorization is deny-by-default.

### Gate 1 audit

Structured journald or append-oriented JSON is sufficient.

Capture:

- request/action ID
- subject
- canonical tool
- canonical resource
- decision
- result/exit status
- duration

Do not log raw secrets.

## 4. Gate 2 Scoped pilot

Add policy parsing/validation inside Broker.

Unknown fields/capabilities fail closed.

Define one real stack.

Possible tools:

~~~text
file.read
service.status
service.restart
docker.logs
docker.action
job.status
~~~

Do not add unrestricted Docker socket access.

Docker remains Broker-only and typed.

Run for several days and record real missing capabilities.

## 5. Gate 3 durable state

Only now add SQLite if needed.

Only Broker opens:

~~~text
/var/lib/vps-agent/state.db
~~~

Enable WAL.

Suggested state:

- jobs
- idempotency / operation journal
- resource locks
- audit metadata
- later approvals/grants

Rules:

- short transactions
- no external command inside DB transaction
- busy timeout/backoff
- logical locks with deadlines for long operations
- every resource lock has owner/action_id + monotonically increasing fencing token
- stale owners cannot release or commit against a newer fencing token

### Operation journal

Before a replay-protected external side effect:

1. insert/claim the invocation as `PENDING`
2. commit the short transaction
3. perform the external effect
4. mark `DONE` and persist the result

If the process crashes between steps 3 and 4, the next request returns `reconcile-required` or runs an action-specific reconciler. It must not blindly repeat the effect.

### Idempotency

Gateway/integration layer creates retry identity as infrastructure metadata when a stable retry identity exists.

Bind to:

~~~text
subject + canonical tool + normalized request hash + invocation identity
~~~

Never infer retry merely because arguments are identical.

## 6. Jobs

Internal model:

~~~text
job.start
job.status
job.tail
job.cancel
~~~

A job runs in its own managed systemd unit/cgroup when appropriate.

Persist:

- owner
- policy/grant
- resource
- action
- unit/pid
- created/deadline
- status
- exit code

The MCP connection may disappear without losing job state.

## 7. Secrets

Prefer:

- root-owned files outside repo
- systemd LoadCredential / credential directory

Broker resolves secret references.

No plaintext secret retrieval tool.

Test that stdout/stderr/audit do not trivially expose known test secrets.

## 8. Gate 4 broader writes

Add only demonstrated capabilities.

### Files

Implement safe resolution and atomic writes.

Preferred openat2; secure fallback or fail closed.

For configuration changes:

~~~text
backup/temporary write
 -> native validator
 -> atomic replace
 -> reload/restart
 -> healthcheck
 -> rollback when safe
~~~

Examples:

~~~text
nginx -t
docker compose config
systemd unit validation
~~~

### Sandboxed shell.exec

Only if typed tools are insufficient.

Run under systemd transient unit/cgroup.

Enforce:

- cwd roots
- timeout
- MemoryMax
- TasksMax
- output limit
- cancellation
- filtered environment
- network policy

Landlock is optional defense-in-depth.

## 9. ChatGPT authentication/distribution

This stage is implemented for the supported integrated self-hosted OAuth path. Follow docs/chatgpt-integration.md and docs/authentication.md.

The implementation validates active token state, issuer, dedicated audience/resource, expiration, subject and required scopes through private introspection, while the Broker rechecks the expected subject and policy.

## 10. Gate 5 elevation

Optional elevation machinery exists and is acceptance-tested, but it does not constitute a Full/R5 production claim. Full remains disabled by default and Scoped remains the supported product path.

Historical gate rule: only add elevation after Scoped proves insufficient.

Enable feature:

~~~yaml
features:
  full_mode_enabled: true
~~~

Add:

- elevation request
- operator out-of-band approval
- one-time nonce
- temporary explicit capabilities
- expiry
- revoke-all
- separate network elevation
- enhanced audit

An operator approval UI may be hosted by Gateway, but Broker validates the signed operator identity/assertion and nonce independently.

Only after this is tested consider shell.exec_admin.

## 11. Lease and job semantics

Default:

~~~text
job_deadline <= grant_expiry
~~~

When an elevated grant expires:

- no new privileged mutations
- graceful termination
- force termination after bounded grace period
- persist final state
- audit

A special completion grant may be used only with explicit operator approval.

## 12. Recovery

### Broker restart
- reconcile persisted jobs with systemd units/processes
- adopt monitoring or terminate according to policy

### SQLite corruption
- fail closed
- invalidate pending approvals
- treat elevated grants as revoked
- preserve damaged DB
- restore verified backup
- reconcile active jobs
- re-enable after integrity checks

### Emergency

Provide an operator command outside the AI surface:

~~~text
vps-agent revoke-all
~~~

It revokes elevated grants and blocks new elevated starts.

## 13. systemd hardening

Gateway:

- User=vps-agent
- NoNewPrivileges=yes
- ProtectSystem=strict
- ProtectHome=yes
- PrivateTmp=yes
- only required ReadWritePaths
- no Docker socket

Broker:

- root-owned
- no TCP listener
- Unix socket only
- minimal API
- fixed config/runtime paths
- journald
- restart-on-failure

Review with systemd-analyze security.

## 14. Production acceptance

### Scoped production
Require at least:

- Gate 0A/0B/1/2 passed
- negative authorization tests
- safe filesystem tests for enabled writes
- recovery test
- secrets test
- client path proven
- existing workloads survive Gateway/Broker stop

### Full production
Additionally:

- Full explicitly enabled
- approval tested
- expiry tested
- revoke-all tested
- network capability separation tested
- remote audit checkpointing tested
- admin shell containment/recovery tested

## 15. Rollback

The agent gateway must remain an optional control plane.

Stopping Gateway/Broker and removing its route must not stop existing application workloads.

That property is mandatory.