Skip to content

CLI attestation init fails with digest mismatch when server doesn’t return digest from Save RPC #2998

Description

@javirln

During attestation init with remote state, the PR metadata collector runs multiple times (observed 13 consecutive collections) before EvaluateAttestationPolicies fails with a state digest conflict.

Each successful collector save updates the server-side state, but the client-side digest tracking falls out of sync, causing the final policy evaluation write to be rejected by the OCC check.

ERR evaluating attestation policies: failed to persist crafting state: failed to save state:
rpc error: code = Aborted desc = saving attestation: failed to save attestation state:
the provided base digest doesn't match the stored state, it might have changed,
got="bb994066...", want="87664418..."

Reproduction

Set up a local GitHub Actions environment:

# Runner detection
export CI=true
export GITHUB_REPOSITORY="owner/repo"
export GITHUB_RUN_ID="12345"

# Runner metadata
export GITHUB_ACTOR="johndoe"
export GITHUB_REF="refs/pull/123/merge"
export GITHUB_REPOSITORY_OWNER="owner"
export GITHUB_SHA="abc123def456"
export RUNNER_NAME="local-runner"
export RUNNER_OS="macOS"

# PR-specific (triggers PR metadata collection)
export GITHUB_EVENT_NAME="pull_request"
export GITHUB_HEAD_REF="feature-branch"
export GITHUB_BASE_REF="main"
export GITHUB_EVENT_PATH="/tmp/github_event.json"

# Event payload
cat > /tmp/github_event.json << 'EOF'
{
  "pull_request": {
    "number": 123,
    "title": "Add new feature",
    "body": "This PR adds a new feature",
    "html_url": "https://github.com/owner/repo/pull/123",
    "user": { "login": "johndoe" },
    "requested_reviewers": [
      { "login": "reviewer1", "type": "User" }
    ]
  }
}
EOF

Then run:

chainloop attestation init --workflow <name> --project <name> --version v0 --replace --remote-state

Expected: PR metadata collected once, policy evaluation succeeds.

Actual: PR metadata collected 13 times, policy evaluation fails with digest mismatch.

Analysis

Two issues are at play:

  1. The PR metadata collector runs multiple times instead of once during RunCollectors. This needs investigation — possible duplicate collector registration or retry loop.

  2. After collectors finish, the RunCollectors workaround (added in fix: return digest from attestation state save for OCC support #2909) reloads state only if UpdateCheckSum changed. With multiple saves, the digest tracking can fall out of sync between client and server, causing EvaluateAttestationPolicies (added in feat(policies): add attestation phase lifecycle control #2765) to fail when it tries to save with a stale digest.

  3. Use Chainloop version v1.73.1 server and latest CLI

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions