Outcall
SpecificationsS013 · Agent-Name Rule Context

Functional requirements

S013: Agent-Name Rule Context — Functional Requirements

FR-001: AgentContext type in outcall-api

Requirement: Add AgentContext to outcall-api/src/lib.rs with a name: String field.

Rationale: The CEL evaluation context needs a structured agent identity type. AgentContext is optional because resolution may fail (see EC-001, EC-002).

Acceptance: AgentContext is serializable, cloneable, and has a Default impl.

FR-002: agent field in EvalContext

Requirement: Add pub agent: Option<AgentContext> to EvalContext in outcall-api/src/lib.rs.

Rationale: EvalContext is the top-level CEL context struct. Adding agent exposes the resolved identity to CEL expressions without breaking existing callers (Option field with Default means None for backwards-compatible JSON serialization).

Acceptance: Existing EvalContext JSON roundtrip tests still pass (no new required fields).

FR-003: SO_PEERCRED to container name resolution

Requirement: In the Unix socket accept path (where PermissionRequest arrives from the agent), read SO_PEERCRED to obtain the caller's PID. Resolve PID → container IP via /proc/<PID>/status, then call DockerManager::lookup_container_name_by_ip(ip) to get the container name.

Rationale: SO_PEERCRED is the only reliable way to identify the calling container on a Unix domain socket. The existing container_name_for_ip already handles the Docker API lookup.

Acceptance: A request from agent container foobar-1 produces container name "foobar-1".

FR-004: Agent name derived from container name

Requirement: Strip the trailing -N (where N is a decimal number) from the container name to derive agent_name. If the container name has no trailing -N pattern, use the full container name as the agent name.

Rationale: The established naming convention uses -N suffix for replica indexing. Agents expect agent.name == "foobar" to match all replicas (foobar-1, foobar-2, etc.).

Acceptance:

  • "foobar-1"name = "foobar"
  • "my-agent-12"name = "my-agent"
  • "standalone"name = "standalone" (no suffix to strip)

FR-005: agent.name exposed in CEL

Requirement: In rules/engine.rs, add agent.name as a CEL variable binding so that CEL expressions can reference agent.name directly.

Rationale: CEL evaluation requires explicit variable bindings. Adding agent.name to the evaluation context makes it available in all rule conditions.

Acceptance: A rule with condition agent.name == "foobar" evaluates correctly for container foobar-1.

FR-006: DockerContext.image remains unchanged

Requirement: The existing DockerContext.image field must not be modified or deprecated. Both docker.image and agent.name coexist in the evaluation context.

Rationale: docker.image identifies the container image; agent.name identifies the agent identity. They serve different purposes and both are needed.

Acceptance: Existing rules using docker.image == "..." continue to work unchanged.

EC-001: SO_PEERCRED not available (non-Unix socket)

If the rule evaluation request arrives over a non-Unix socket (e.g., HTTP over TCP), SO_PEERCRED is not available. In this case, AgentContext should be None.

Handling: build_eval_context receives a reference to the raw socket (or a flag) indicating whether SO_PEERCRED is available. If not, agent: None.

EC-002: Container IP not found in DockerManager

If SO_PEERCRED returns a valid PID but the container IP cannot be resolved (/proc/<PID>/status missing or DockerManager has no entry for that IP), AgentContext should be None.

Handling: container_name_for_ip already returns Option<String>. Propagate None through the resolution chain.

EC-003: Agent name with no trailing -N

Handling: The strip function should only strip when the suffix matches -[0-9]+$. If no match, return the full name. This preserves container names that genuinely do not follow the -N pattern.

EC-004: Async resolution does not block rule evaluation

Handling: The PID → container name resolution is synchronous (reads /proc and checks an in-memory HashMap in DockerManager). It must not do an async Docker API call during rule evaluation. lookup_container_name_by_ip on DockerManager is already async but returns instantly from the cache. Ensure the cache is populated on container join (S008) so that rule evaluation never hits a Docker API delay.

On this page