-
Notifications
You must be signed in to change notification settings - Fork 0
docs: establish identity product and architecture baseline #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
seonghobae
merged 33 commits into
main
from
docs/product-architecture-baseline-2026-08-09
Aug 11, 2026
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
2644054
docs: add canonical documentation map
seonghobae d427218
docs: add canonical product requirements
seonghobae 43d6002
docs: add canonical technical requirements
seonghobae 084cef8
docs: add identity runtime UML views
seonghobae 77d132d
docs: add identity control-plane ERD
seonghobae 2a7a024
docs: add identity threat model
seonghobae 64efc5a
docs: add identity test strategy
seonghobae 57a13cd
docs: add identity operability guide
seonghobae 34848dc
docs: add identity requirements traceability
seonghobae 967303a
docs: add identity ADR index
seonghobae 9c833b5
docs: record identity hub ADR
seonghobae b120c09
docs: record passwordless ADR
seonghobae 54bb818
docs: record identity matching ADR
seonghobae 9330856
docs: record reconciliation ADR
seonghobae e5c336d
docs: record configuration ownership ADR
seonghobae a5c3a8b
docs: record user-operation lock ADR
seonghobae 1bf79ae
docs: record automation authority ADR
seonghobae ee38d88
test: enforce canonical identity documentation
seonghobae 7ce6512
test: tighten identity documentation contracts
seonghobae c10d05a
docs: tighten active-PR and SCIM lock boundaries
seonghobae 54edc0c
docs: scope shared user-operation lock to implemented paths
seonghobae f1c1569
docs: distinguish SCIM PUT and PATCH lock coverage
seonghobae e8fa0de
docs: define tenant and receipt identity constraints
seonghobae 5b718b3
docs: use explicit research and operations terminology
seonghobae 14dec35
docs: clarify Naruon and SCIM operating scope
seonghobae 5987c8d
docs: separate Keycloak and Keyverse storage authority
seonghobae a6cf52c
docs: align identity traceability maturity and lock scope
seonghobae 0a1d441
docs: align SCIM lock and RP redirect contracts
seonghobae 4d28410
docs: name canonical research and runbook records
seonghobae 1c834e6
docs(authz): record the non-fork RP authorization boundary
552fcae
docs(authz): record downstream dependency gate
c8e3656
docs(authz): make RP contract reproducible
4da37dc
docs(authz): track latest SDP review head
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Keyverse Documentation Map | ||
|
|
||
| Keyverse already has strong feature-specific specifications, doctoring, federation/onboarding, topology, and operations records. This index makes the cross-cutting product and architecture graph explicit without replacing those slice documents. | ||
|
|
||
| | Area | Canonical document | | ||
| |---|---| | ||
| | Product requirements | [`docs/PRD.md`](docs/PRD.md) | | ||
| | Technical requirements | [`docs/TRD.md`](docs/TRD.md) | | ||
| | Architecture | [`ARCHITECTURE.md`](ARCHITECTURE.md) | | ||
| | Topology | [`docs/topology.md`](docs/topology.md) | | ||
| | UML/runtime/authority flows | [`docs/UML.md`](docs/UML.md) | | ||
| | Logical/physical ERD | [`docs/ERD.md`](docs/ERD.md) | | ||
| | Threat model | [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) | | ||
| | Test strategy | [`docs/TEST_STRATEGY.md`](docs/TEST_STRATEGY.md) | | ||
| | Operability/recovery/release | [`docs/OPERABILITY.md`](docs/OPERABILITY.md) | | ||
| | Requirements/evidence traceability | [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md) | | ||
| | Architecture decisions | [`docs/adr/README.md`](docs/adr/README.md) | | ||
| | Federation onboarding | [`docs/federation-onboarding.md`](docs/federation-onboarding.md) | | ||
| | RP onboarding | [`docs/rp-onboarding.md`](docs/rp-onboarding.md) | | ||
| | Account merge/unification | [`docs/merge-unification-flow.md`](docs/merge-unification-flow.md) | | ||
| | Standards/APA 7 evidence | [`docs/doctoring/`](docs/doctoring/) and [`docs/papers/`](docs/papers/) | | ||
| | Operations | [`docs/operations/`](docs/operations/) | | ||
| | Security reporting | [`SECURITY.md`](SECURITY.md) | | ||
| | Agent instructions | [`AGENTS.md`](AGENTS.md) | | ||
| | Agent context | [`CLAUDE.md`](CLAUDE.md) | | ||
| | Product overview | [`README.md`](README.md) | | ||
| | Change history | [`CHANGELOG.md`](CHANGELOG.md) | | ||
|
|
||
| ## Maturity vocabulary | ||
|
|
||
| - **implemented-main** — present on protected main with source/tests. | ||
| - **active-PR** — implemented only on an open PR and not yet a protected-main claim. | ||
| - **deployment-owned** — private tenant/customer secret/configuration behavior owned by deployment controller/secret store. | ||
| - **external-system** — Keycloak/ADFS/LDAP/external OIDC/HR/IGA behavior not implemented by Keyverse itself. | ||
| - **planned** — accepted target without executable implementation. | ||
|
|
||
| Open PR #72 OIDC RP claim mapper profile and PR #74 hourly GitHub API remediation remain active-PR until merged. Keyverse's current protected-main desired-state/reconciliation capabilities are documented independently from those changes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,208 @@ | ||
| # Keyverse Logical and Persistence ERD | ||
|
|
||
| **Status:** Accepted cross-cutting data model. Exact Keycloak internal schema remains Keycloak-owned. | ||
| **Last reviewed:** 2026-08-09 | ||
|
|
||
| Keyverse persists its own configuration, desired-state, receipts, merge audit, and user-operation locks while Keycloak/PostgreSQL owns canonical IdP users/sessions/clients/federation runtime state. This ERD models Keyverse-owned durable records and their relation to external Keycloak identities without pretending to own Keycloak's internal tables. | ||
|
|
||
| ```mermaid | ||
| erDiagram | ||
| IDP_CONFIG_ENTRY }o--|| TENANT_DEPLOYMENT : scoped_to | ||
| FEDERATION_SOURCE }o--|| TENANT_DEPLOYMENT : scoped_to | ||
| DIRECTORY_FEDERATION_SOURCE }o--|| TENANT_DEPLOYMENT : scoped_to | ||
| RELYING_PARTY_SOURCE }o--|| TENANT_DEPLOYMENT : scoped_to | ||
|
|
||
| FEDERATION_SOURCE ||--o{ FEDERATION_APPLY_RECEIPT : produces | ||
| DIRECTORY_FEDERATION_SOURCE ||--o{ DIRECTORY_FEDERATION_APPLY_RECEIPT : produces | ||
| RELYING_PARTY_SOURCE ||--o{ RELYING_PARTY_APPLY_RECEIPT : produces | ||
|
|
||
| KEYCLOAK_USER_REFERENCE ||--o{ ACCOUNT_MERGE_AUDIT : survivor_or_duplicate | ||
| KEYCLOAK_USER_REFERENCE ||--o| USER_OPERATION_LOCK_STATE : guarded_by | ||
| KEYCLOAK_USER_REFERENCE ||--o{ EXTERNAL_IDENTITY_LINK : owns | ||
| EXTERNAL_IDENTITY_LINK }o--|| FEDERATION_SOURCE : originates_from | ||
|
|
||
| TENANT_DEPLOYMENT { | ||
| uuid tenant_deployment_id PK | ||
| text deployment_name | ||
| text deployment_status_code | ||
| timestamptz created_at | ||
| } | ||
|
|
||
| IDP_CONFIG_ENTRY { | ||
| uuid idp_config_entry_id PK | ||
| uuid tenant_deployment_id FK | ||
| text config_key | ||
| text protected_value_ref | ||
| text config_version | ||
| timestamptz updated_at | ||
| } | ||
|
|
||
| FEDERATION_SOURCE { | ||
| uuid federation_source_id PK | ||
| uuid tenant_deployment_id FK | ||
| text federation_alias | ||
| text protocol_code | ||
| jsonb secret_free_desired_state | ||
| text desired_state_hash | ||
| text lifecycle_status_code | ||
| timestamptz updated_at | ||
| } | ||
|
|
||
| FEDERATION_APPLY_RECEIPT { | ||
| uuid federation_apply_receipt_id PK | ||
| uuid federation_source_id FK | ||
| uuid apply_attempt_id UK | ||
| text desired_state_hash | ||
| text keycloak_resource_id | ||
| text observed_state_hash | ||
| text apply_outcome_code | ||
| timestamptz observed_at | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| DIRECTORY_FEDERATION_SOURCE { | ||
| uuid directory_federation_source_id PK | ||
| uuid tenant_deployment_id FK | ||
| text directory_alias | ||
| jsonb private_desired_state | ||
| text desired_state_hash | ||
| text lifecycle_status_code | ||
| timestamptz updated_at | ||
| } | ||
|
|
||
| DIRECTORY_FEDERATION_APPLY_RECEIPT { | ||
| uuid directory_federation_apply_receipt_id PK | ||
| uuid directory_federation_source_id FK | ||
| uuid apply_attempt_id UK | ||
| text desired_state_hash | ||
| text keycloak_component_id | ||
| text observed_state_hash | ||
| text apply_outcome_code | ||
| timestamptz observed_at | ||
| } | ||
|
|
||
| RELYING_PARTY_SOURCE { | ||
| uuid relying_party_source_id PK | ||
| uuid tenant_deployment_id FK | ||
| text client_id | ||
| jsonb secret_free_desired_state | ||
| text desired_state_hash | ||
| text lifecycle_status_code | ||
| timestamptz updated_at | ||
| } | ||
|
|
||
| RELYING_PARTY_APPLY_RECEIPT { | ||
| uuid relying_party_apply_receipt_id PK | ||
| uuid relying_party_source_id FK | ||
| uuid apply_attempt_id UK | ||
| text desired_state_hash | ||
| text keycloak_client_uuid | ||
| text observed_state_hash | ||
| text apply_outcome_code | ||
| timestamptz observed_at | ||
| } | ||
|
|
||
| KEYCLOAK_USER_REFERENCE { | ||
| uuid keycloak_user_reference_id PK | ||
| uuid tenant_deployment_id FK | ||
| text keycloak_user_uuid | ||
| text lifecycle_status_code | ||
| } | ||
|
|
||
| EXTERNAL_IDENTITY_LINK { | ||
| uuid external_identity_link_id PK | ||
| uuid tenant_deployment_id FK | ||
| uuid keycloak_user_reference_id FK | ||
| uuid federation_source_id FK | ||
| text external_subject_hash | ||
| boolean email_verified | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| ACCOUNT_MERGE_AUDIT { | ||
| uuid account_merge_audit_id PK | ||
| uuid tenant_deployment_id FK | ||
| uuid survivor_user_reference_id FK | ||
| uuid duplicate_user_reference_id FK | ||
| text match_evidence_code | ||
| text operation_outcome_code | ||
| uuid actor_identity_id | ||
| timestamptz occurred_at | ||
| } | ||
|
|
||
| USER_OPERATION_LOCK_STATE { | ||
| uuid user_operation_lock_state_id PK | ||
| uuid keycloak_user_reference_id FK | ||
| text operation_type_code | ||
| text lock_owner_token | ||
| timestamptz acquired_at | ||
| timestamptz lease_expires_at | ||
| } | ||
| ``` | ||
|
|
||
| ## Logical uniqueness constraints | ||
|
|
||
| UUID primary identifiers are globally unique. Human/provider identifiers are scoped to the owning tenant or federation source and MUST NOT be interpreted as global keys. | ||
|
|
||
| | Entity | Required logical uniqueness | | ||
| |---|---| | ||
| | `IDP_CONFIG_ENTRY` | `(tenant_deployment_id, config_key)` | | ||
| | `FEDERATION_SOURCE` | `(tenant_deployment_id, federation_alias)` | | ||
| | `DIRECTORY_FEDERATION_SOURCE` | `(tenant_deployment_id, directory_alias)` | | ||
| | `RELYING_PARTY_SOURCE` | `(tenant_deployment_id, client_id)` | | ||
| | `KEYCLOAK_USER_REFERENCE` | `(tenant_deployment_id, keycloak_user_uuid)` | | ||
| | `EXTERNAL_IDENTITY_LINK` | `(federation_source_id, external_subject_hash)` | | ||
|
|
||
| `federation_source_id` defines the identity-provider scope for the external-subject uniqueness rule. Within one federation source, one normalized/hashed external subject may link to at most one Keycloak user reference. This prevents one issuer/provider subject from being attached to multiple users while still allowing unrelated providers to use the same subject string. | ||
|
|
||
| Physical migrations must enforce these constraints in the owning Keyverse store. Documentation labels such as `client_id`, `federation_alias`, or Keycloak UUID never authorize cross-tenant lookup by themselves. | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| Tenant-qualified composite foreign keys are mandatory for cross-entity identity | ||
| references. At minimum, the physical schema MUST enforce: | ||
|
|
||
| - `EXTERNAL_IDENTITY_LINK (tenant_deployment_id, keycloak_user_reference_id)` → | ||
| `KEYCLOAK_USER_REFERENCE (tenant_deployment_id, keycloak_user_reference_id)`; | ||
| - `EXTERNAL_IDENTITY_LINK (tenant_deployment_id, federation_source_id)` → | ||
| `FEDERATION_SOURCE (tenant_deployment_id, federation_source_id)`; | ||
| - `ACCOUNT_MERGE_AUDIT (tenant_deployment_id, survivor_user_reference_id)` → | ||
| `KEYCLOAK_USER_REFERENCE (tenant_deployment_id, keycloak_user_reference_id)`; | ||
| - `ACCOUNT_MERGE_AUDIT (tenant_deployment_id, duplicate_user_reference_id)` → | ||
| `KEYCLOAK_USER_REFERENCE (tenant_deployment_id, keycloak_user_reference_id)`. | ||
|
|
||
| The referenced tenant-qualified pairs MUST be unique keys. A child row carrying | ||
| only a globally unique UUID is insufficient evidence of tenant isolation; the | ||
| database constraint must reject a mismatched tenant even when application code | ||
| or documentation labels are bypassed. | ||
|
|
||
| ## Identity and authorization rules | ||
|
|
||
| - Keycloak UUIDs, federation aliases, RP client IDs, email values, and external subjects are data identifiers, not authorization by themselves. | ||
| - Exact external identity key is `(identity_provider, subject)`; verified email may support matching under policy but unverified email never authorizes linking. | ||
| - `tenant_deployment_id` is explicit in Keyverse-owned records; deployment/customer separation must not be inferred from realm/resource names. | ||
| - Secrets are referenced through protected values/handles where possible; secret-free desired-state tables must never gain client/bind credentials accidentally. | ||
|
|
||
| ## Desired-state and receipt invariant | ||
|
|
||
| ```mermaid | ||
| flowchart LR | ||
| PRIVATE[Private rendered input] | ||
| VALID[Preflight validation] | ||
| INTENT[Versioned desired-state source] | ||
| REMOTE[Keycloak live state] | ||
| RECEIPT[Version-bound apply receipt] | ||
|
|
||
| PRIVATE --> VALID | ||
| VALID --> INTENT | ||
| INTENT --> REMOTE | ||
| REMOTE --> RECEIPT | ||
| ``` | ||
|
|
||
| Every apply receipt records the exact `desired_state_hash` that was acted on as well as the canonical `observed_state_hash`, outcome, unique `apply_attempt_id`, and observation time. A receipt is current for a source only when its `desired_state_hash` equals that source's current desired-state hash. The latest current receipt is the greatest `observed_at` among receipts for that exact desired-state hash; a receipt for an older hash is historical evidence and cannot establish convergence for a newer desired state. | ||
|
|
||
| Retry handling is idempotency-aware. Reusing the same `apply_attempt_id` must return/reuse the same receipt rather than create a second logical attempt. A retry under a new attempt ID may create another receipt, but it remains a distinct attempt and must still bind to the exact desired-state hash. Delete flows that require remote-first semantics cannot remove local desired state before remote deletion succeeds. | ||
|
|
||
| ## Keycloak ownership | ||
|
|
||
| Users, sessions, roles, groups, credentials, WebAuthn material, IdP runtime representation, LDAP storage components, and RP clients ultimately live in Keycloak's schema/API. Keyverse stores controlled references/intent/receipts but does not duplicate or directly edit unsupported Keycloak internal tables. | ||
|
|
||
| ## Migration acceptance | ||
|
|
||
| Changes to Keyverse-owned persistence require migrations/rollback, transaction/concurrency tests, indexes/constraints, tenant isolation, secret/logging tests, backup/restore impact, and ERD/operability/ADR synchronization. Keycloak upgrades require supported schema migration through Keycloak, not custom manipulation of its private database tables. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| # Keyverse Operability, Recovery, and Release Guide | ||
|
|
||
| **Status:** Accepted cross-cutting operating baseline | ||
| **Last reviewed:** 2026-08-09 | ||
|
|
||
| Feature-specific procedures under `docs/operations/`, federation/RP onboarding, and deployment READMEs remain authoritative for their slices. This guide defines the shared operating model and evidence needed before declaring the identity platform healthy or release-ready. | ||
|
|
||
| ## Health model | ||
|
|
||
| Distinguish these conditions: | ||
|
|
||
| 1. **process liveness:** Keycloak/admin process responds; | ||
| 2. **component readiness:** database/config/bootstrap and core dependencies are usable; | ||
| 3. **desired-state convergence:** configured federation/directory/RP state matches Keycloak; | ||
| 4. **protocol acceptance:** controlled login/logout/token/SCIM/bind/search behavior succeeds; | ||
| 5. **downstream authorization acceptance:** RP accepts expected issuer/audience/claims and applies its own authorization policy. | ||
|
|
||
| A lower-level green state never implies a higher-level state. | ||
|
|
||
| ## Key SLIs | ||
|
|
||
| - Keycloak/admin readiness and latency; | ||
| - login/passkey success/error rates; | ||
| - SCIM mutation success/conflict/retry/lock contention; | ||
| - account merge/link outcomes and rollback/tombstone anomalies; | ||
| - desired-state drift and reconciliation age; | ||
| - federation/LDAP/RP apply/re-observation failures; | ||
| - duplicate remote resource detections; | ||
| - user-operation lock wait/expiry/recovery; | ||
| - token issuer/audience/claim acceptance failures; | ||
| - database/storage availability and transaction errors; | ||
| - secret/config bootstrap failures; | ||
| - hourly governance run outcomes without false-green classification. | ||
|
|
||
| Do not put raw tokens, secrets, passwords/bind credentials, protected private payloads, or unnecessary PII into metrics/logs. | ||
|
|
||
| ## Federation onboarding runbook | ||
|
|
||
| 1. render private tenant configuration from approved KV/secret source; | ||
| 2. run authenticated side-effect-free Keyverse preflight; | ||
| 3. review exact policy result; | ||
| 4. persist/apply desired state through the owning reconciliation path; | ||
| 5. verify exact post-mutation Keycloak state/receipt; | ||
| 6. for LDAP/AD perform controlled bind/search/login acceptance after explicit apply; | ||
| 7. for SAML/OIDC perform controlled login/issuer/subject/email/trust checks; | ||
| 8. monitor convergence/errors; | ||
| 9. retain rollback data until acceptance criteria expire. | ||
|
|
||
| ## RP onboarding runbook | ||
|
|
||
| 1. submit secret-free client representation; | ||
| 2. preflight redirects/origins/logout/PKCE/scopes/type; | ||
| 3. reconcile exact Keycloak client and receipt; | ||
| 4. provision confidential secret through the separate secret-management path if needed; | ||
| 5. configure RP securely; | ||
| 6. run authorization-code/PKCE login/logout/token audience/claim acceptance; | ||
| 7. validate downstream authorization separately from authentication. | ||
|
|
||
| For every non-fork RP, record the exact Keyverse issuer, audience, JWKS/key | ||
| rotation source, claim-to-tenant mapping, ABAC/RBAC result, cross-tenant denial | ||
| result, and production-mode fail-closed result. A successful Keyverse client | ||
| receipt or mapper check is not sufficient acceptance evidence. | ||
|
|
||
| PR #72's mapper profile requires the same acceptance after merge: operators must test the **Naruon** product login/token/authorization journey using the `naruon-web` RP client ID and verify the expected audience and bounded claims. Mapper unit tests alone do not prove Naruon product authorization readiness. | ||
|
|
||
| ## Account merge recovery | ||
|
|
||
| Merge and SCIM full replacement (`PUT`) must hold the shared operation lock. Protected-main `PATCH active=false` is not currently inside that shared-lock guarantee and must not be treated as transactionally serialized with merge. On failure, classify whether state changed in Keycloak, Keyverse audit, linked identities, or tombstone status. Re-observe before retry. Never infer a retry is safe solely from the previous HTTP response. Preserve survivor and duplicate lineage in audit. | ||
|
|
||
| ## Desired-state recovery | ||
|
|
||
| On controller/API crash after intent but before receipt: | ||
|
|
||
| - read persisted desired state; | ||
| - query exact remote Keycloak state; | ||
| - classify converged, absent, duplicate, or drifted; | ||
| - reconcile idempotently; | ||
| - write receipt only after exact re-observation and bind it to the desired-state version/hash that was applied. | ||
|
|
||
| On delete, keep local intent until remote-first deletion has succeeded where required. | ||
|
|
||
| ## Database/backup | ||
|
|
||
| Back up Keycloak PostgreSQL and Keyverse-owned configuration/audit/intent/receipt state according to deployment RPO/RTO. Restore through supported Keycloak/database procedures, then run reconciliation and controlled authentication/provisioning acceptance. Do not edit unsupported Keycloak internal tables as a normal recovery technique. | ||
|
|
||
| ## Upgrade/rollback | ||
|
|
||
| - review Keycloak release/migration notes and Keyverse CHANGELOG/ADRs; | ||
| - rehearse database migration and Helm/Compose upgrade; | ||
| - validate realm/config/template compatibility; | ||
| - run merge/SCIM/federation/RP suites; | ||
| - canary controlled login/provisioning; | ||
| - roll back application/config where safe and use supported DB backup/restore for incompatible schema migrations; | ||
| - re-run convergence and protocol acceptance after rollback. | ||
|
|
||
| ## Automation incident RCA | ||
|
|
||
| PR #74 demonstrates that a workflow can appear successful while doing no useful work if a GitHub API gate fails open. Scheduled governance must classify transport failure separately from a valid empty/unhealthy result, fit its time budget, keep provider secrets in the broker phase only, and require exact `success` for protected evidence. After PR #74 merges, operational closure requires a real protected-main scheduled/manual run. | ||
|
|
||
| ## Release gate | ||
|
|
||
| Release only after protected-head CI/security/review, 100% coverage/docstrings, realm/package/deployment validation, migrations/rollback/backup, passkey/federation/SCIM/RP controlled acceptance, secret scan, SBOM/provenance/image digest, runbooks/support, and CHANGELOG/version artifacts are coherent. A merged PR is not a release by itself. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.