feat(relay): promote attribute release to default#488
Conversation
Signed-off-by: Jeremi Joslin <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dbd9f2f5d6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if &expression[start..index] == "context" | ||
| || matches!(bytes.get(member_index), Some(b'.' | b'[')) | ||
| { | ||
| roots.insert(expression[start..index].to_string()); |
There was a problem hiding this comment.
Track only the first member in each CEL chain
When a valid source-only expression contains nested dotted access or a method call, such as source.person.name or source.name.startsWith('A'), this scanner also records the intermediate identifier (person or name) because it is followed by a dot. validate_expression_authority then sees roots other than source and rejects the profile during configuration loading, even though the expression never leaves the projected source authority. Stop scanning the remainder of a member chain as independent roots, and cover nested and method access in the authority tests.
Useful? React with 👍 / 👎.
| local digest | ||
| digest="$(jq -r '."containerimage.digest"' "${metadata}")" | ||
| local digest_ref="${REGISTRY}/${IMAGE_NAMESPACE}/${name}@${digest}" | ||
| local -a expected_label_args=() |
There was a problem hiding this comment.
Commit b3d09322b137cac437b5d394d9a633403b3d7b32 has no Signed-off-by trailer, so it violates the repository's DCO requirement and will be rejected by the contribution gate; recreate the commit with the required sign-off before merging.
AGENTS.md reference: AGENTS.md:L68-L70
Useful? React with 👍 / 👎.
| "Profile not found or not visible to the authenticated principal. \ | ||
| Does not confirm whether the profile ever existed." |
There was a problem hiding this comment.
Declare the mandatory Data-Purpose header in OpenAPI
Every promoted attribute-release profile now requires an exactly matching Data-Purpose header, but the resolve operation's generated parameter list contains only the two path parameters and optional trust-context headers. Clients generated from this newly canonical OpenAPI contract therefore omit Data-Purpose and receive 400 auth.purpose_required for every otherwise valid resolution. Add the required header parameter to this operation and regenerate the committed OpenAPI output.
AGENTS.md reference: AGENTS.md:L82-L86
Useful? React with 👍 / 👎.
Signed-off-by: Jeremi Joslin <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e796a9fc2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| local digest | ||
| digest="$(jq -r '."containerimage.digest"' "${metadata}")" | ||
| local digest_ref="${REGISTRY}/${IMAGE_NAMESPACE}/${name}@${digest}" | ||
| local -a expected_label_args=() |
There was a problem hiding this comment.
Add the sign-off to the rewritten commit
Fresh evidence after the prior DCO comment: the rewritten commit d2bb4d66df8dcc6d7baf22c8f7cc16f2c202c947 itself still has no Signed-off-by trailer. The repository's DCO workflow checks every commit and will reject this one, so recreate it with git commit -s before merging.
AGENTS.md reference: AGENTS.md:L70-L70
Useful? React with 👍 / 👎.
| COPY --from=builder /usr/local/bin/registry-relay /usr/local/bin/registry-relay | ||
| COPY --from=builder /usr/local/bin/registry-relay-rhai-worker /usr/local/bin/registry-relay-rhai-worker | ||
| COPY LICENSE /licenses/registry-relay/LICENSE | ||
| LABEL org.registrystack.registry-relay.features="${REGISTRY_RELAY_FEATURES}" |
There was a problem hiding this comment.
Record effective features in the image label
For a documented custom build such as REGISTRY_RELAY_FEATURES=attribute-release, Cargo also activates crosswalk-runtime transitively via attribute-release = ["crosswalk-runtime"], but this label records only the literal build argument. The resulting image therefore claims one feature while /admin/v1/capabilities reports both, making the new feature-provenance evidence inaccurate; normalize the transitive feature closure or reject incomplete override lists before applying the label.
AGENTS.md reference: AGENTS.md:L79-L81
Useful? React with 👍 / 👎.
| } | ||
| } | ||
| }, | ||
| "description": "Invalid request: malformed body, unknown id_type, empty claims list, or unsupported media type." |
There was a problem hiding this comment.
Document the runtime 415 response
When the resolve request has a missing or non-JSON Content-Type, the Json extractor returns 415, as asserted by resolve_rejects_non_json_content_type, but this newly canonical contract classifies an unsupported media type as 400 and declares no 415 response. Generated clients will therefore handle the actual rejection incorrectly; add a 415 response in the OpenAPI generator and regenerate this artifact.
AGENTS.md reference: AGENTS.md:L82-L86
Useful? React with 👍 / 👎.
| "description": "Subject identifier value. Never logged or echoed in responses.", | ||
| "type": "string" |
There was a problem hiding this comment.
Allow every supported subject scalar in OpenAPI
For profiles backed by numeric or boolean subject fields, the runtime explicitly accepts JSON strings, numbers, and booleans in scalar_subject_value, while the canonical request schema restricts subject.value to a string. OpenAPI validators and generated clients will reject valid numeric/boolean requests or coerce them to strings, potentially changing equality matching against the source field; declare the value as a string/number/boolean union in the generator and regenerate the artifact.
AGENTS.md reference: AGENTS.md:L82-L86
Useful? React with 👍 / 👎.
| support_owner: none | ||
| feature_frozen: true | ||
| canonical_release: false | ||
| stability_tier: stable |
There was a problem hiding this comment.
Split the change across owning areas
This single change modifies independently owned surfaces under crates/registry-relay, crates/registryctl, docs/site, and release, despite the repository rule that a change remain scoped to one owning area. Split the promotion into owner-scoped changes so each area's contract and required gates can be reviewed independently.
AGENTS.md reference: AGENTS.md:L77-L78
Useful? React with 👍 / 👎.
Signed-off-by: Jeremi Joslin <[email protected]>
Signed-off-by: Jeremi Joslin <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8ce6d9c04e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| local digest | ||
| digest="$(jq -r '."containerimage.digest"' "${metadata}")" | ||
| local digest_ref="${REGISTRY}/${IMAGE_NAMESPACE}/${name}@${digest}" | ||
| local -a expected_label_args=() |
There was a problem hiding this comment.
Fresh evidence after the prior DCO comments: the latest rewritten commit 0a50fc5784766cf82fcb816a43c96e85897b364b still has no Signed-off-by trailer. The repository's DCO workflow checks every commit and will reject this one, so recreate it using git commit -s before merging.
AGENTS.md reference: AGENTS.md:L68-L70
Useful? React with 👍 / 👎.
| && !value.contains(',') | ||
| && !value | ||
| .chars() | ||
| .any(|character| character.is_control() || character.is_whitespace()) |
There was a problem hiding this comment.
Restrict header-bound purposes to visible ASCII
When a mandatory profile purpose contains a non-ASCII token such as identité, this validator accepts it because the characters are neither whitespace nor control characters. However, purpose_header_value reads Data-Purpose through HeaderValue::to_str(), which rejects every non-visible-ASCII byte, so no request can ever match the configured purpose and every resolution returns auth.purpose_required. Validate the header-bound purpose as visible ASCII (or define a reversible wire encoding) so an accepted profile remains usable.
Useful? React with 👍 / 👎.
| if !entity.api.required_filters.is_empty() { | ||
| return release_error( | ||
| "attribute_release_profiles cannot use an entity with required_filters because the caller-supplied subject cannot satisfy a principal-bound filter", | ||
| ); | ||
| } |
There was a problem hiding this comment.
Mirror release prerequisites in Registryctl validation
When a Registryctl records service combines an attribute-release profile with nonempty required_principal_filters, the authoring schema and validate_record_attribute_release_profiles accept it and generate the entity, but this new Relay validation rejects that generated configuration during Registryctl's production-loading check. The same mismatch occurs when the authored pagination max_limit is 1 because the adjacent Relay check requires at least 2. Add these cross-field prerequisites to Registryctl's authoring validation so schema-valid projects fail early with an actionable authoring error instead of always failing generated-product activation.
Useful? React with 👍 / 👎.
| enabled: set[str] = set() | ||
| pending = list(defaults) | ||
| while pending: |
There was a problem hiding this comment.
Derive stability from canonical release features
When a future developer-default feature is added to Cargo.toml, this checker will treat its routes as eligible for stable status and canonical OpenAPI coverage solely because it starts from features.default. The release recipe deliberately builds with --no-default-features and an explicit attribute-release,crosswalk-runtime list so developer defaults cannot expand the published binary; therefore the assurance checks could approve a stable route that is absent from the release. Derive this set from the canonical release feature profile instead of the mutable developer default.
Useful? React with 👍 / 👎.
What
Why
Attribute release is the maintained Notary/Relay integration path. Shipping it as an optional variant would create multiple production profiles and leave the official image unable to exercise that path. The hardening in this change closes the gaps found while reviewing promotion readiness.
The initial CI run exposed a stale assurance invariant that treated every feature-gated route as optional and experimental. The checker now permits stable routes only behind Cargo features enabled by default, while preserving the experimental requirement for optional feature gates.
Security
sourceauthority, including dotted and bracketed access checksprivate, no-storeVerification
just ciin Registry Relayjust ci-preflightin Registry Relayjust exposure-checkin Registry Relaypython3 -m unittest tests/security_assurance_check_test.pypython3 scripts/check_security_assurance.py openapi-coveragejust openapi-contract origin/maincargo test --locked -p registryctl project_authoringpython3 -m unittest discover -s release/scripts -p 'test_*.py'npm testandnpm run checkindocs/sitecargo treereview for RUSTSEC-2023-0089Refs #487
Follow-up release evidence
After the next Registry Stack version is published, Solmara Lab still needs to pin the official Relay image by digest and record the live journey evidence. This PR prepares and verifies the canonical binary and image contract but cannot produce that future release digest.