diff --git a/api/openapi-handler-exceptions.yaml b/api/openapi-handler-exceptions.yaml index 6c5e86c..ed8a604 100644 --- a/api/openapi-handler-exceptions.yaml +++ b/api/openapi-handler-exceptions.yaml @@ -25,3 +25,32 @@ documented_exceptions: why: "SCEP-mTLS sibling endpoint, trailing-slash variant." - route: "POST /scep-mtls/" why: "SCEP-mTLS sibling endpoint, trailing-slash POST variant." + + # ACME server (RFC 8555 + RFC 9773 ARI) — wire-protocol surface. + # Like SCEP/EST, ACME is a JWS-signed-JSON wire protocol whose + # semantics are dictated by the RFC, not by an OpenAPI schema. + # Documenting every endpoint in openapi.yaml would duplicate + # RFC 8555 §7.1 + §7.2 + §7.3 with no information gain. The + # canonical operator-facing reference is docs/acme-server.md. + # Phases 2-4 will extend this list as new-order, finalize, authz, + # challenge, cert, key-change, revoke-cert, renewal-info routes land. + - route: "GET /acme/profile/{id}/directory" + why: "ACME server RFC 8555 §7.1.1 directory; documented in docs/acme-server.md." + - route: "HEAD /acme/profile/{id}/new-nonce" + why: "ACME server RFC 8555 §7.2 new-nonce; documented in docs/acme-server.md." + - route: "GET /acme/profile/{id}/new-nonce" + why: "ACME server RFC 8555 §7.2 new-nonce GET form; documented in docs/acme-server.md." + - route: "POST /acme/profile/{id}/new-account" + why: "ACME server RFC 8555 §7.3 new-account (JWS jwk); documented in docs/acme-server.md." + - route: "POST /acme/profile/{id}/account/{acc_id}" + why: "ACME server RFC 8555 §7.3.2 + §7.3.6 (JWS kid) account update + deactivation; documented in docs/acme-server.md." + - route: "GET /acme/directory" + why: "ACME server default-profile shorthand; mirrors per-profile when CERTCTL_ACME_SERVER_DEFAULT_PROFILE_ID is set." + - route: "HEAD /acme/new-nonce" + why: "ACME server default-profile shorthand for new-nonce HEAD." + - route: "GET /acme/new-nonce" + why: "ACME server default-profile shorthand for new-nonce GET." + - route: "POST /acme/new-account" + why: "ACME server default-profile shorthand for new-account." + - route: "POST /acme/account/{acc_id}" + why: "ACME server default-profile shorthand for account update + deactivation." diff --git a/go.mod b/go.mod index 1c3c7e9..b19a20a 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.41.7 github.com/aws/aws-sdk-go-v2/config v1.32.17 github.com/aws/aws-sdk-go-v2/service/acmpca v1.46.14 + github.com/go-jose/go-jose/v4 v4.0.4 github.com/leanovate/gopter v0.2.11 github.com/masterzen/winrm v0.0.0-20250927112105-5f8e6c707321 github.com/pkg/sftp v1.13.10 diff --git a/scripts/ci-guards/G-3-env-docs-drift.sh b/scripts/ci-guards/G-3-env-docs-drift.sh index b629006..233f371 100755 --- a/scripts/ci-guards/G-3-env-docs-drift.sh +++ b/scripts/ci-guards/G-3-env-docs-drift.sh @@ -61,7 +61,9 @@ CERTCTL_TLS_INSECURE_SKIP_VERIFY| CERTCTL_SCEP_| CERTCTL_SERVER_CA_BUNDLE_PATH| CERTCTL_SERVER_TLS_INSECURE_SKIP_VERIFY| -CERTCTL_QA_[A-Z_]+ +CERTCTL_QA_[A-Z_]+| +CERTCTL_ACME_| +CERTCTL_ACME_SERVER_ )$' # ^ The CERTCTL_OPENSSL_* / CERTCTL_STEPCA_* / CERTCTL_WEBHOOK_* / # CERTCTL_ACME_EAB_* / CERTCTL_ACME_DNS_PROPAGATION_WAIT / @@ -70,6 +72,16 @@ CERTCTL_QA_[A-Z_]+ # (script invocations, per-issuer config-blob field names, # per-notifier config-blob field names, demo-stack overrides, # test fixtures) — not server-side env vars in config.go. +# +# CERTCTL_ACME_ + CERTCTL_ACME_SERVER_ are bare-prefix forms +# operator docs use to describe namespace separation between the +# consumer-side ACMEConfig (full names like CERTCTL_ACME_DIRECTORY_URL +# defined in config.go) and the ACME server's CERTCTL_ACME_SERVER_* +# prefix (full names like CERTCTL_ACME_SERVER_ENABLED defined in +# config.go::ACMEServerConfig). The bare prefixes themselves are +# never read by config.go — they're only doc prose — so they +# allowlist alongside the existing CERTCTL_SCEP_ + CERTCTL_TLS_ +# bare-prefix entries. # The audit's "37 docs-only" count over-flagged these; the # closure narrows the gate to the specific drift sites # (renewal-interval rename + 6 config-only) and allowlists