Expose
cmd/crewship/cmd_expose.go is the human side of port exposures. Agents create exposures themselves by calling the sidecar’s /expose-port endpoint; this CLI is for the audit (list) and teardown (revoke) verbs. MVP doesn’t ship approve because the default policy is open — when a future policy introduces approval, the approve verb lands here next to the others.
All subcommands scope to one crew because the server enforces crew-level auth on the underlying routes.
Container runtime requirements
expose list and expose revoke work everywhere — they are plain API calls. The capability URLs themselves do not: crewshipd proxies them by dialing the crew container on its Docker bridge IP, with no host port published anywhere, so it must be able to route to the container network directly.
On an affected runtime
expose list still shows the exposure as ACTIVE — the row is real and the token is valid. Opening the URL returns 502 with a body naming the unreachable target address. That is the symptom to look for; it is a routing constraint, not a bug in the exposure. See Port Expose — container runtime requirements.
crewship expose list
GET /api/v1/crews/{crewId}/port-expose.
Columns:
ID (14-char trunc), AGENT, PORT, STATUS, EXPIRES, DESCRIPTION (40-char trunc).
crewship expose revoke <id>
POST /api/v1/crews/{crewId}/port-expose/{id}/revoke. Flips an active exposure to REVOKED. Requires MANAGER+ (same as escalation resolve).
Revoke prompts for confirmation (
Revoke port exposure "<id>" on crew "<slug>"?) before it fires; pass --yes to skip it in scripts.
Exposure <id> revoked.
See also
crewship credential— adjacent secrets surface (different access pattern).crewship audit— full audit trail including revoke reasons.crewship agent— the agent identity that initiated the exposure.