TwinEthosRequest access

Control

Agent actions not traceable to identity and owner

Every agent action must be attributable to a distinct agent identity and an accountable human/owner.

Informational data, not legal advice. Summaries are TwinEthos's own words and rules have not been reviewed by a lawyer: check the official text before relying on any of it. A guard addresses an item; adding it is not a statement that your code meets any law.

Family: An AI agent's authority, reach, inputs, and components are not bounded and accountable · control id cond.agent-actions-not-traceable-to-identity-and-owner

Reach

2items this one guard addresses
0jurisdictions where binding law on it is in force
0more where it is enacted, not yet applying
1standards and frameworks on the same control

The guard to add

Give each agent its own credential and a registry entry naming an accountable owner, and log every tool action with agent_id, owner, action, target, and timestamp.

A registry (agents.yaml, agent_registry.json, or an IaC-declared inventory) lists each agent's id, accountable owner, and scope. The runtime authenticates each agent as itself: a per-agent service principal, workload identity, or an agent-specific API key looked up by agent_id, never a shared SERVICE_API_KEY and never the end user's bearer token forwarded into tool clients. The tool executor refuses calls from an agent missing from the registry and, for every call it runs, writes an append-only audit record (agent_id, owner, run_id, tool, target, timestamp, outcome) or an OpenTelemetry span carrying gen_ai.agent.id. Agents cannot create or assume other identities.

Where it goes: 15 agent action surface, 3 config and feature flags, 10 logs and telemetry, 12 repository artifacts.

What reviewers look for: a registry file mapping every agent to an owner; credentials resolved per agent_id on the tool path (not os.environ['SERVICE_API_KEY'] shared by all agents, not request.headers['Authorization'] passed into tool or agent clients); an audit_log.append(agent_id=..., owner=...) call or gen_ai.agent.id span on every tool execution, exported to a retained, append-only sink.

Example (Python agent tool executor), before:

def run_tool(call, request):
    headers = {'Authorization': request.headers['Authorization']}   # end user's token
    return requests.post(TOOL_URLS[call.name], json=call.arguments, headers=headers)

After:

REGISTRY = yaml.safe_load(open('agents.yaml'))   # id -> owner, scope, credential_ref

def run_tool(agent_id, call):
    entry = REGISTRY[agent_id]                       # KeyError: unregistered agents cannot act
    token = secret_store.get(entry['credential_ref'])  # this agent's own credential
    resp = requests.post(TOOL_URLS[call.name], json=call.arguments,
                         headers={'Authorization': f'Bearer {token}'})
    audit_log.append(agent_id=agent_id, owner=entry['owner'], action=call.name,
                     target=TOOL_URLS[call.name], ts=time.time(), status=resp.status_code)
    return resp

Engineering guidance, not legal advice. Each provision below may add its own details (a cadence, a deadline, a required notice element): open it for those.

Every rule this guard addresses

Standard / soft law (1)

TwinEthos recommendation (not law) (1)

Related incidents