feat(certificatemanager): add CertificateMap, DnsAuthorization and TrustConfig - #171
Merged
Merged
Conversation
…ustConfig Certificate Manager was absent from the plugin. These three are the types that need nothing external: a map with no entries, an authorization that only hands back a CNAME, and a trust config with no stores are all valid and free. Left out deliberately: Certificate needs either a PEM keypair committed to the repository or a domain that actually resolves; CertificateIssuanceConfig needs a privateca CA pool; CertificateMapEntry needs a certificate to point at. All three fit the generic engine - location-scoped, create id as a query parameter, patch with a query-string field mask - so there is no custom provisioner here, which is a first for this run of batches. DnsAuthorization drops both name and domain from update bodies: domain is immutable and UpdateMaskFromBody builds the mask from the body's top-level fields, so leaving it in would put an unchangeable field in the mask and have the patch rejected. Verification runs through debug-conformance: the local key is 403 on this service, as it is on DNS and Bigtable.
Create failed for all three types with
Malformed name: '.../locations/europe-central2/certificateMaps/...'
[Invalid location in resource URL path]
Certificate maps, DNS authorizations and trust configs are global; inheriting
the target's region addresses a location the API does not have. The path
builder pins "global" rather than the fixtures pinning it, which keeps create
and discovery pointed at the same place - a fixture that pins a region leaves
the discovery pass looking somewhere else, which is what makes API Gateway
undiscoverable in this project.
The ScopeLocationBased scope is gone with it: it makes List return nothing
whenever the target declares no location, which is exactly the case for a
global resource.
The fixture asserted that a trust config with no stores is valid and trusts nothing, and the schema comment said the same. Certificate Manager rejects it: "trust config must contain at least one trust store or allowlisted certificate". Create never got off the ground, so nothing behind it had ever run. The fixture now pins one throwaway self-signed anchor, inline rather than read from a file so the case carries its own input and holds no private key. The blank line before the closing delimiter is load-bearing. Certificate Manager appends a trailing newline to every pemCertificate it stores, whatever was sent - a PEM posted without one comes back with one - so a fixture declaring it without the newline passed Create and then failed Verify, Extract, Sync and Update against its own certificate. A declared PEM has to carry the newline the API will add. Recorded in the CHANGELOG, because it bites any forma with an inline PEM. All three certificate manager cases now pass locally, CRUD and discovery 4/4.
naxty
marked this pull request as ready for review
August 31, 2026 15:02
naxty
added a commit
that referenced
this pull request
Aug 31, 2026
…ustConfig Restores #171. That pull request was stacked, and it merged into its parent branch rather than into main - GitHub marks a stacked pull request merged once its commits reach its base, and its base was a branch. #167, #168, #169 and #170 went the same way but were recovered when #173 landed, because #173 descended from them. Nothing descended from #171, so certificate manager was the one batch left behind: main has carried a Merged badge and no code since. This is that content on top of current main, nothing else - the three types, their schemas, six fixtures, and the package registration. Verified locally against the service account CI uses, all three CRUD 7/7 with Replace skipped and discovery 4/4. Two things it needed, both recorded in the CHANGELOG: roles/certificatemanager.owner rather than editor, which carries no delete permission at all; and a trust config that is not empty, since the API rejects one carrying neither a trust store nor an allowlisted certificate.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Adds Certificate Manager, which was absent from the plugin. Stacked on #170.
GCP::CertificateManager::CertificateMapcertmanager-certificate-mapGCP::CertificateManager::DnsAuthorizationcertmanager-dns-authorizationGCP::CertificateManager::TrustConfigcertmanager-trust-configVerified locally, not yet in CI. The runs are on this branch with the
service account CI uses; CI will run them when this reaches the merge train.
The grant this was blocked on — and why the original ask was wrong
The draft asked for
roles/certificatemanager.editor. That role is not enough:it carries every
.createpermission and no.deletepermission at all(only
deleteTagBinding). With it, Create through Update pass and Destroy failswith
Permission 'certificatemanager.dnsauthorizations.delete' denied— whichlooks like a plugin bug and is not one.
roles/certificatemanager.owneris the minimal role that covers a conformancerun. It is now granted to
github-deploy@(CI) andformae-tester@(local).Two real defects the grant exposed
Neither was visible while everything failed at Create on a permission denial.
A trust config cannot be empty. The fixture and the schema comment both
claimed a config with no stores "is valid and trusts nothing". Certificate
Manager rejects it:
trust config must contain at least one trust store or allowlisted certificate. The fixture now pins one throwaway self-signed anchor,inline, so the case carries its own input and holds no private key.
Certificate Manager appends a trailing newline to every
pemCertificate.Whatever you send, it comes back with one — a PEM posted without a trailing
newline is stored with it. So the first fixed fixture passed Create and then
failed Verify, Extract, Sync and Update against its own certificate. A declared
PEM has to carry the newline the API will add; in the fixture that is the blank
line before the closing
""", which is load-bearing and commented as such.This one bites any forma with an inline PEM, not just this fixture, so it is
recorded in the CHANGELOG. It is not fixed in the plugin: normalising on read
would break the forma that does end its PEM with a newline, and normalising on
write does not change what the comparison sees. Matching the API's form is the
behaviour a
read()of a real.pemfile gives for free, since PEM files endwith a newline by convention.
What is still not covered
Replace is skipped for all three — no
-replace.pklfixtures.Certificateand
CertificateMapEntryare not in this batch.