LearnNewsExamplesServices
Frontmatter
id16532
titleData Sync mints tokens with a deprecated app-id, and the rename alone breaks auth
stateOpen
labels
bugai
assignees[]
createdAtAug 5, 2026, 9:44 AM
updatedAtAug 5, 2026, 9:44 AM
githubUrlhttps://github.com/neomjs/neo/issues/16532
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]

Data Sync mints tokens with a deprecated app-id, and the rename alone breaks auth

neo-opus-ada
neo-opus-ada commented on Aug 5, 2026, 9:44 AM

Context

Every Data Sync pipeline run emits four deprecation warnings:

Input 'app-id' has been deprecated with message: Use 'client-id' instead.

Non-fatal today. Filed because a deprecation is an error with a delay: when actions/create-github-app-token promotes app-id from deprecated to removed, the pipeline stops minting tokens and the hourly Data Sync fails at the first step — before any of the completeness and freshness guards that were built this week get a chance to report anything useful.

Surfaced by @tobiu while reviewing run 30971652217: "warnings tend to become errors, once old renamings switch deprecated to removed."

The Problem

Two sites, both in .github/workflows/data-sync-pipeline.yml, both actions/create-github-app-token@v3:

line step secret
:73 Mint Publisher installation token DATA_SYNC_PUBLISHER_APP_ID
:87 Mint Intake installation token DATA_SYNC_INTAKE_APP_ID

These are the only app-id usages in .github/workflows/. No other workflow mints an App token.

The part that makes this not a rename

A GitHub App's Client ID is a different value from its App ID. The App ID is numeric (123456); the Client ID is a string (Iv23li…). Both secrets are named …_APP_ID, which strongly implies they hold App IDs.

So app-id:client-id: alone breaks token minting: the action would receive an App ID in a field expecting a Client ID and fail authentication. The migration needs the secret values repopulated from each App's settings page — and repository secrets are operator-owned, not something this ticket can deliver.

That asymmetry is the whole reason to file this now rather than at removal time: the obvious one-line fix is wrong, and discovering that while the pipeline is already broken is the expensive path.

Blast radius when it does break

Both identities die at once. The publisher mints the token that pushes the corpus to dev; the intake identity is the only credential with an installation on the DevIndex repos — GITHUB_TOKEN cannot substitute, as the workflow's own comment records: "absent, not merely underprivileged." So a removal turns into a total pipeline outage, not a degraded run.

The Architectural Reality

  • actions/create-github-app-token@v3 at data-sync-pipeline.yml:71 and :85
  • The two-identity split is deliberate and documented in-file: one App spanning all three repos would let the publishing identity mutate intake repos and vice versa. This ticket must not collapse the two identities — the migration is per-identity and preserves the split.
  • permission-contents: write is requested explicitly on the publisher so the grant is reviewable in the diff. Any migration keeps that property.

The Fix

  1. Confirm, per App, whether the existing secret holds an App ID or a Client ID. The secret name is not evidence.
  2. If App IDs (expected): the operator adds DATA_SYNC_PUBLISHER_CLIENT_ID / DATA_SYNC_INTAKE_CLIENT_ID from each App's settings. Add beside, do not overwrite — an in-place swap makes rollback impossible if the new value is wrong, and the pipeline is hourly.
  3. Switch both steps to client-id:.
  4. Verify on a workflow_dispatch run before the next scheduled run, since a failed mint is a full outage.
  5. Retire the old secrets only after a green scheduled run.

Steps 1, 2 and 5 are operator-owned; 3 and 4 are the agent-deliverable slice.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
data-sync-pipeline.yml:73 / :87 input key this ticket client-id replaces app-id old secrets retained until a green scheduled run in-file comments unchanged dispatch run mints both tokens
DATA_SYNC_*_CLIENT_ID secrets operator new values from each App's settings added beside the old ones, never overwritten mint step succeeds
two-identity split unchanged publisher and intake stay separate Apps existing in-file rationale both steps still present
permission-contents: write unchanged still requested explicitly existing in-file rationale diff review

Decision Record impact

none. Workflow input key plus repository secrets.

Acceptance Criteria

  • Neither app-id nor any other deprecated input remains in .github/workflows/, verified by grep rather than by reading the diff.
  • A workflow_dispatch run mints both tokens successfully before any scheduled run depends on it.
  • The publisher/intake identity split is intact — two Apps, two secrets, unchanged rationale comments.
  • permission-contents: write is still requested explicitly on the publisher.
  • The deprecation warnings are gone from the run log — the observable that started this.
  • Old secrets are retired only after a green scheduled run, not at merge.

Out of Scope

  • Upgrading create-github-app-token beyond v3. A major bump is a separate change with its own surface; this ticket removes a deprecated input on the pinned version.
  • Revisiting the two-identity split. Deliberate, documented, and load-bearing for mutation-authority separation.
  • Other deprecated Actions inputs. If the grep in AC 1 surfaces more, they get their own ticket rather than widening this one — but the grep is deliberately phrased to find them.

Avoided Traps

  • Treating it as a key rename. The obvious one-line fix breaks authentication, because App ID and Client ID are different values. This is the finding.
  • Overwriting the existing secrets. An hourly pipeline with no rollback path is the wrong place to discover a bad value.
  • Waiting for removal. Migrating under a green pipeline is cheap; migrating under an outage means diagnosing a credential failure and a value mismatch simultaneously.
  • Collapsing the two Apps while touching both steps. The split is the security property.

Related

  • #16428 — the auto-maintained Data Sync alarm; this is a future failure mode for the same pipeline, not its current cause
  • #16495 / PR #16496 — the chromadb cause of the current breach, merged 30338b40b0
  • #16530 / PR #16531 — the failure-message classification that made the current breach hard to read

Live latest-open sweep at 2026-08-05T07:50Z: 200 open issues scanned for app-id|client-id|deprecat|create-github-app-token; no equivalent found. A2A in-flight claim sweep could not be run — the Memory Core MCP server is unavailable. Recorded as a gap rather than skipped silently; if a peer holds this scope, this ticket yields by first-claim timestamp.

Origin Session ID: eeacb603-97f1-4241-9b2f-3a542cab6d2c

Retrieval Hint: query_raw_memories("create-github-app-token app-id client-id deprecation data sync") · data-sync-pipeline.yml:73