Amend ADR-020 and ADR-021: the no-callbacks constraint scopes to the GitLab instance
🔍 Why is this change being made?
artifact-registry#1279 moves the IAM relationship-response cache out of per-pod process memory into the key-value store the Artifact Registry is already provisioned. Its first acceptance criterion is this MR, and it gates the S25 spec MR.
Three of the four edits are precision, not decision. Both ADRs cite the interface agreement's no-callbacks constraint as their source, and that agreement already scopes the rule the way this MR states it:
Artifact Registry never calls back to the GitLab instance, Rails, or any remote service during request processing. […] This constraint targets services that may be unreachable — co-located platform services on the SaaS side (e.g., the relationships API) are not subject to this constraint.
The test is reachability, and the exemption is an open example. The ADRs restated both less precisely.
✏️ What changed
📡 ADR-020, the architectural constraint
Said the Artifact Registry never calls back to "the GitLab instance, Rails, or any remote service" while processing a request. Read literally, that forbids the per-request relationships-API call ADR-021 sanctions, so it contradicted shipped behavior. It now names the instance alone and says the dependencies the Artifact Registry is itself deployed and provisioned with are not its target.
🐛 ADR-020, the flow legend
Called the out-of-band issuer-key sync "the only remote dependency" two rows above the legend's own steps 5-6, which describe a per-request call to the relationships API. It is authentication's only remote dependency. The constraint paragraph above the diagram carried the same unscoped count, and now reads "one remote dependency for authentication" to match.
🔒 ADR-021, the constraint bullet
Two problems, both load-bearing:
- It turned the agreement's open example into a closed two-item list — "the relationships API and the GLAZ policy-engine sidecar" — so a reader takes the key-value store and the relational database as forbidden by omission. The exemption is now a criterion, dependencies that share the Artifact Registry's failure domain, with the four current ones as examples. This also stops the exemption resting on co-location, which is a topology claim the infrastructure agreement owns and which does not hold uniformly: GLAZ is a same-pod sidecar, the relationships API is a separate service behind a headless service.
- The bullet ends "If a dependency is unavailable, authorization fails closed." Adding the key-value store to that list would make the ADR mandate a denial on a cache outage — the opposite of what #1279 requires, where a store outage degrades to a direct relationships-API call with no authorization failures. The rule now applies to a dependency the decision needs an answer from, and explicitly not to a cache.
🔄 ADR-021, the relationship cache
This one is a decision change. It reverses half of the trade-off recorded in !21025 (merged):
That cache is in-process rather than backed by the key-value store the Artifact Registry is provisioned: no network hop on the authorization path and no shared-cache dependency, paid for with non-atomic invalidation. A key-value-backed cache would hold one entry with one expiry for the whole fleet.
The first benefit was not real. The authorization path already crosses the network to reach the relationships API, so the in-process cache bought no hop-free property; it only divided the collapse rate by the instance count. The cache is now recorded as backed by the provisioned key-value store, and the "one entry with one expiry for the whole fleet" property that sentence named as the alternative is the one we take. The cost is stated plainly, including that losing the store degrades the cache rather than failing the decision.
The closing security instruction is kept, on a new basis. It previously rested on per-instance expiry, which this decision removes. It now rests on per-key expiry, which the same bullet already establishes two sentences earlier ("keyed on … the target resources"): a caller holding entries for several resources loses them at different moments, so a denial on one resource still does not establish that the revocation has taken hold on the others. That is narrower than the per-instance version, which the shared cache no longer supports for the resource the denial was about.
🤝 What this MR does not do
agreements/auth.md is not edited. It is an approved interface agreement with the Auth Platform team, and its rationale sentence is already correct — editing it unilaterally would gate #1279 on a cross-team review. But its exemption names platform services rather than the Artifact Registry's own backing stores, so the alignment is recorded in ADR-021's existing "Interface agreement alignment" open question, which already exists for exactly this kind of drift on the role vocabulary.
Checked and left alone because nothing in them contradicts the amendment: ADR-006 §6 (which already requires a Redis-compatible service for "caching … and ephemeral shared application state"), ADR-024 (which lists the Runway-provisioned Memorystore cache), ADR-023, both agreements, and the eight other places in these two ADRs that state the constraint against the GitLab instance or Rails specifically.
No front matter, heading, or anchor changed, so no incoming links or redirects are owed.
✅ Validation
markdownlint-cli2— 0 issuesvale --minAlertLevel error— 0 errors, 0 warnings, 0 suggestions- Swept both ADRs for
any remote service,in-process,no network hop,per-instance,per-pod,only remote dependency: no surviving hit - Swept
decisions/andagreements/for conflicting claims; confirmed the three link anchors still resolve - No Hugo build: prose-only edits to two existing pages, no shortcode, front matter, or navigation change
📚 Related
- artifact-registry#1279 — the implementation this unblocks
- !21025 (merged) — the amendment whose in-process trade-off this revises
- artifact-registry#527 — the full-clear path #1279 subsumes
- The S25, S09, and S05-A specs, the configuration reference, and
config.example.yamlstill describe the cache as per-pod. Those are Artifact Registry repo surfaces that cite ADR-021 as their authority, so they follow this MR rather than lead it.
Author and Reviewer Checklist
Please verify the check list and ensure to tick them off before the MR is merged.
- Provided a concise title for this Merge Request (MR)
- Added a description to this MR explaining the reasons for the proposed change, per say why, not just what
- Assign reviewers for this MR to the correct
- For transparency, share this MR with the audience that will be impacted.
- Team: For changes that affect your direct team, share in your group Slack channel
Commits
%{all_commits}