Skip to content
SHAMPOO

Tool catalogue

107 documented tools.

Derived from the canonical SHAMPOO tool documentation (the same source the implementation is gated against), so these pages and the software cannot drift apart.

7 tools

Authentication

Enrolment, handshakes, revocation and session administration.

handshake_challenge

Write · Internal

Begins a hybrid session handshake and returns a one-time challenge with the server's ephemeral key material. Spoke machinery only; completion must run on the same connection.

Full documentation →

Arguments, result and boundaries
Arguments
Required: `ref_kind`, `ref_id`. Optional: `client_instance_id`, `client_kind`, `client_name`, `client_version`, `transport`, `user_agent`. - `ref_kind`. Note: One of bootstrap, ticket. - `ref_id`. Note: Shape-checked only here; validity is never decided until complete, so refs cannot be probed. - `client_instance_id`. Note: Optional client metadata stored with the challenge slot; never authority. - `client_kind`. Note: Optional session kind (client or spoke), bound into the session row at complete; absent means legacy direct. Invalid values fail the challenge. - `client_name`. Note: Optional client metadata stored with the challenge slot; never authority. - `client_version`. Note: Optional client metadata stored with the challenge slot; never authority. - `transport`. Note: Optional client metadata stored with the challenge slot; never authority. - `user_agent`. Note: Optional client metadata stored with the challenge slot; never authority.
Result
Object with challenge_id, server_ecdh and server_kem public material, suite, and expires_in seconds.
Boundaries
Pre-authentication call on the same connection that must later complete. Challenge slots are single-process, bounded (64), and expire after 300 seconds. Ordinary users never call this directly; spokes do.
Lifecycle
Holds one single-use challenge with fresh ephemeral P-256 plus ML-KEM-768 public material. The slot is consumed by exactly one complete attempt, success or failure.
Errors
Bad ref shape, invalid client kind, overlong metadata, or a full challenge heap deny generically as a normal handshake failed payload. No failure leaks whether a ref exists.
Example
```json { "ref_id": "<uuid>", "ref_kind": "ticket" } ``` Result shape: ```json { "challenge_id": "<uuid>", "expires_in": 300, "server_ecdh": "<b64u>", "server_kem": "<b64u>", "suite": "HYBRID{P-256,ML-KEM-768}+HKDF-SHA512+A256GCM" } ```

handshake_complete

Write · Internal

Completes a hybrid handshake: derives the shared secret, verifies the credential envelope, and returns a sealed session response. Single use per challenge; any failure denies generically.

Full documentation →

Arguments, result and boundaries
Arguments
Required: `challenge_id`, `client_ecdh`. Optional: `envelope_ct`, `envelope_iv`, `envelope_tag`, `kem_ct`, `profile`. - `challenge_id`. Note: Single-use; unknown, reused, or expired ids deny generically. - `client_ecdh`. Note: Caller ephemeral P-256 public material; exact length required. - `envelope_ct`. Note: Credential envelope ciphertext carrying a bootstrap or ticket credential. - `envelope_iv`. Note: Envelope nonce; exact length required. - `envelope_tag`. Note: Envelope tag; exact length required. - `kem_ct`. Note: ML-KEM-768 ciphertext; exact length required. - `profile`. Note: Requested profile boundary only, never authority: unknown names deny like bad credentials, and the credential check runs against the selected profile's own grants.
Result
Sealed response envelope object with iv, ct, and tag; inside are session_id, client_id, expires_at, session credential, bound profile, and (ticket path only) the new bootstrap secret.
Boundaries
Pre-authentication call bound to the challenge's connection. Ticket enrolment burns the ticket, provisions the principal, and opens the session atomically; grants come from server-held entries only, never caller claims. Ordinary users never call this directly.
Lifecycle
Derives the hybrid secret over the full transcript, opens the credential envelope, verifies a bootstrap or ticket credential, opens a 1-hour registry session, mints its credential, and seals the session response. Post-commit failures revoke the just-made session rather than leaving it orphaned.
Errors
Every failure shape (bad challenge, bad key lengths, transcript mismatch, envelope failure, unknown credential, full key heap) denies generically as handshake failed with no oracle.
Example
```json { "challenge_id": "<uuid>", "client_ecdh": "<b64u>" } ``` Result shape: ```json { "ct": "<b64u>", "iv": "<b64u>", "tag": "<b64u>" } ``` Real calls also carry kem_ct and the envelope_iv/ct/tag triplet; the sealed session response is an iv/ct/tag envelope.

issue_enrollment_ticket

Write · Conductor only

Issues a one-time enrolment ticket binding a server-side grant to a single secret. Call it to enrol a new principal without sharing credentials.

Full documentation →

Arguments, result and boundaries
Arguments
Required: `user`, `projects`. Optional: `reason`, `role`, `ticket_kind`, `ttl_seconds`. - `user`. Note: Server-side grant subject, required. - `projects`. Note: Server-side grant, required; bound into the ticket and never taken from the later handshake caller. - `reason`. - `role`. Note: agent or conductor; defaults agent. - `ticket_kind`. Note: Optional designation for spoke enrolment (spoke or standard, default standard); stored on the ticket. Installations that disallow spokes refuse spoke-kind issuance. - `ttl_seconds`. Note: Defaults 3600.
Result
Object with ticket_id, secret (shown once; deliver out-of-band), and a note.
Boundaries
Conductor role required. The grant (user, role, projects) is fixed server-side at issue; the secret travels only inside the later encrypted bootstrap envelope.
Lifecycle
Persists a one-time ticket bound to the grant. The secret is shown once at issue; redemption burns the ticket and provisions the principal.
Errors
Non-conductor callers get a requires-conductor error payload. Missing user/projects, bad role/TTL/kind, or spoke-kind issuance where spokes are disallowed fail as a ticket issue failed payload.
Example
```json { "projects": "shared-ops", "user": "field-agent" } ``` Result shape: ```json { "note": "secret shown once; deliver out-of-band", "secret": "<secret-once>", "ticket_id": "<uuid>" } ```

kill_session

Write · Conductor only

Revokes one live session immediately. Call it to cut off a single compromised or stuck session without touching its principal.

Full documentation →

Arguments, result and boundaries
Arguments
Required: `session_id`. Optional: `reason`. - `session_id`. - `reason`.
Result
Object with killed (echoed session_id) and matched (1 revoked, 0 untouched).
Boundaries
Conductor role required. Any live session may be targeted; the killed session denies on its very next operation.
Lifecycle
Moves one live session entry to revoked with timestamp and reason. The principal entry is untouched.
Errors
Non-conductor callers get a requires-conductor error payload. Missing session_id is a tool error. Unknown or already-dead sessions report matched 0.
Example
```json { "session_id": "<uuid>" } ``` Result shape: ```json { "killed": "<uuid>", "matched": 1 } ```

list_sessions

Read · Conductor only

Lists server-side session registry entries. Call it to audit live and historical sessions across principals.

Full documentation →

Arguments, result and boundaries
Arguments
Optional: `client_id`, `limit`, `status`. - `client_id`. Note: Narrows to one principal; empty means all. - `limit`. Note: Defaults 20, clamped 1 to 100. - `status`. Note: Narrows by active, revoked, expired, or ended; unknown values match nothing.
Result
Object with sessions array (principal, status, generation, timestamps, transport peer, client application/version/instance, revocation state, profile) and count.
Boundaries
Conductor role required. Returns audit metadata only; no key material exists in the registry by construction.
Lifecycle
Pure registry read; records nothing.
Errors
Non-conductor callers get a requires-conductor error payload. Unknown status values return the empty shape, fail-closed.
Example
```json { "status": "active" } ``` Result shape: ```json { "count": 1, "sessions": [ { "client_id": "<id>", "session_id": "<uuid>", "status": "active" } ] } ```

revoke_agent

Write · Conductor only

Revokes a principal immediately, including all its live sessions. Call it to cut off a compromised agent entirely.

Full documentation →

Arguments, result and boundaries
Arguments
Required: `client_id`. Optional: `reason`. - `client_id`. - `reason`.
Result
Object with revoked (echoed client_id), matched, and sessions_killed counts.
Boundaries
Conductor role required. Revocation bumps the principal generation so every live session denies on its very next operation.
Lifecycle
Moves the principal entry to revoked with a generation bump and revokes all its live sessions. History is retained for operator recovery.
Errors
Non-conductor callers get a requires-conductor error payload. Missing client_id is a tool error. Unknown principals report matched 0.
Example
```json { "client_id": "<uuid>", "reason": "key rotation" } ``` Result shape: ```json { "matched": 1, "revoked": "<uuid>", "sessions_killed": 2 } ```

revoke_ticket

Write · Conductor only

Cancels an unused enrolment ticket. Call it when a ticket was issued in error or is no longer needed.

Full documentation →

Arguments, result and boundaries
Arguments
Required: `ticket_id`. Optional: `reason`. - `ticket_id`. - `reason`.
Result
Object with revoked (echoed ticket_id) and matched (1 cancelled, 0 untouched).
Boundaries
Conductor role required. Only unused tickets flip; used, expired, or revoked tickets report matched 0.
Lifecycle
Moves one unused ticket entry to revoked with a reason. The grant never activates.
Errors
Non-conductor callers get a requires-conductor error payload. Missing ticket_id is a tool error.
Example
```json { "reason": "sent to wrong channel", "ticket_id": "<uuid>" } ``` Result shape: ```json { "matched": 1, "revoked": "<uuid>" } ```