Skip to content

feat(gcpname): canonical parser for workload identity provider names - #2

Merged
discount-elf merged 3 commits into
mainfrom
gcpname
Aug 25, 2026
Merged

feat(gcpname): canonical parser for workload identity provider names#2
discount-elf merged 3 commits into
mainfrom
gcpname

Conversation

@JeroenSoeters

Copy link
Copy Markdown
Contributor

Summary

The workload identity provider resource name is about to be validated in four places across three repositories: the provisioner that creates it, the resource plugin that exchanges a token for it, the credential broker that decides whether to mint for it, and the CLI that registers it. It is worth exactly one parser, because the name is load-bearing twice over — it is the coordinate a GCP cloud connection is registered under, and it is the aud of the identity token minted for that connection.

Two failure modes motivate the strictness:

  • Prefix matching admits a lookalike host. strings.HasPrefix against //iam.googleapis.com also accepts //iam.googleapis.com.evil/projects/.... The prefix constant here includes the following /projects/, and a test mutating it back to the loose form fails.
  • A non-canonical spelling silently breaks the exchange. A name that Google canonicalizes differently from the provisioned one produces a token whose audience does not match, which surfaces much later and reads like an unrelated auth failure. So percent-encoding, query strings, fragments, trailing slashes, extra segments, whitespace and non-ASCII homoglyphs are all refused, and Parse followed by String is the identity function on every accepted input.

Project numbers with a leading zero are refused rather than trimmed: two spellings of one number would mean two spellings of one audience.

The package has no dependencies, so the broker and the plugin can take it without inheriting a cloud SDK.

The provider resource name is both the coordinate a GCP cloud connection is
registered under and the audience of the identity token minted for it, so it
gets validated in four places across three repositories. Validating it by
prefix admits a host that merely starts with the right characters:
strings.HasPrefix against "//iam.googleapis.com" accepts
"//iam.googleapis.com.evil/...". Spelling it differently from the provisioned
form produces a token that silently fails to exchange.

So the grammar is exact rather than a prefix, and Parse followed by String is
the identity function on every accepted input. Percent-encoding, query
strings, fragments, trailing slashes, extra segments, whitespace and non-ASCII
homoglyphs are all refused, each being a way to write a name Google would
canonicalize differently from what was provisioned. Project numbers with a
leading zero are refused rather than trimmed, since two spellings of one
number would mean two spellings of one audience.

The package is dependency-free on purpose: its consumers are a provisioner, a
resource plugin, a credential broker and a CLI.
The package has four consumers across three repositories, and two of them
cannot take the root oox module: the formae CLI pins an older Go than oox
root requires, and the credential broker would inherit oox's cloud SDKs in
its build graph for what is stdlib-only string handling.

Its own module with an empty require block costs every consumer nothing.
Every module in this repo is its own matrix entry, and a new one that is not
listed is a module whose tests never run. Pinned to its declared floor with
auto-upgrade off, like provx: this module exists partly so consumers on an
older Go can take it, and the only thing that proves the floor is building at
the floor.
@discount-elf
discount-elf merged commit be1d2e1 into main Aug 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants