Skip to content

bug(attestation): trailing @ in agentIdentity.binary when version empty (kernel-attested path) #92

@manzil-infinity180

Description

@manzil-infinity180

Summary

On macOS, predicate.agentIdentity.binary in attestations carries a garbled
string instead of a clean filesystem path. Caught live during PR #88 +
SPIRE end-to-end testing.

Observed

With aflock running as MCP-UDS server, claude connecting through a
socat stdio↔UDS bridge, attestations show:

"agentIdentity": {
  "model": "claude-opus-4-7",
  "modelVersion": "4.7.0",
  "binary": "socat1@",
  "binaryHash": "aba6184a9a8390e048193234b027fcbf134bd5306d90c8dd429fdc214b5b40f7",
  "environment": "local",
  "policyDigest": "17b0ca0437974a45bde46e7fd83e855d3420cb7ea01b8200797158dd10add55f",
  "identityHash": "b4d15ed93f404e8b4717bcf90313fda9d2a67799317468214634e5696f70b854"
}

"binary": "socat1@" is not a real filesystem path. Expected something
like /opt/homebrew/bin/socat.

Why it matters

  • binaryHash is fine (sha256 length, deterministic) → identity hash
    computation isn't affected. Phase 2 verify still passes.
  • But binary is part of the human-readable attestation record.
    Auditors looking at attestations see garbage where they expect a path.
  • Indicates a string-handling bug — likely null-byte truncation, or
    lsof output parsing that grabs the wrong column / partial line.

Likely cause

internal/identity/peer_darwin.go uses lsof (LOCAL_PEERPID alone
doesn't give a path on macOS — there's no /proc analog). The lsof
output format is column-based and fragile; one of:

  • Reading non-null-terminated bytes as a Go string
  • Splitting on whitespace and grabbing the wrong token
  • Truncating at the wrong delimiter

Repro

On macOS, run aflock with kernel peer-cred (PR #88 branch):

# Build aflock from fix/identity-discovery-63
cd aflock && go build -o /tmp/aflock ./cmd/aflock

# Start UDS server
/tmp/aflock serve --unix /tmp/test.sock --policy /path/to/.aflock &

# Connect via socat (any peer with a path containing 'socat' in argv[0])
# Trigger an MCP tool call so an attestation is created.

# Inspect agentIdentity.binary in the resulting attestation:
jq '.predicate.agentIdentity.binary' \
  ~/.aflock/sessions/<session>/attestations/*.intoto.json
# Expected: a real path. Observed: "socat1@" or similar garbage.

Files of interest

  • internal/identity/peer_darwin.go — lsof-based path discovery
  • internal/identity/peercred/peercred_darwin.go — LOCAL_PEERCRED + LOCAL_PEERPID

Acceptance

  • agentIdentity.binary shows a clean filesystem path on macOS
  • Add a unit test that injects a representative lsof output line and
    asserts the parser returns the expected path
  • (Bonus) handle the case where lsof returns no rows for a transient PID

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions