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

Fields

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