8000 Appcred auth support by simonepelosi · Pull Request #109 · go-goose/goose · GitHub
[go: up one dir, main page]

Skip to content

Appcred auth support - #109

Merged
SimonRichardson merged 4 commits into
go-goose:v5from
simonepelosi:appcred-auth-support
Oct 16, 2026
Merged

SimonRichardson merged 4 commits into
go-goose:v5from
simonepelosi:appcred-auth-support

Conversation

@simonepelosi
@simonepelosi simonepelosi commented Oct 7, 2026 •
Copy link
Copy Markdown
Contributor

Goose currently supports username+password auth (v2 and v3) and EC2-style access/secret key pairs, but no way to authenticate with an OpenStack application credential
(https://docs.openstack.org/api-ref/identity/v3/#application-credentials) (id+secret) — a distinct Keystone v3 auth method with its own request shape and no explicit project scope (the credential is already scoped to a project at creation time; Keystone rejects a request that both uses an application credential and asks for an explicit scope).

Add AuthApplicationCredentialV3, a new AuthMode alongside the
existing legacy/userpass/userpass-v3 modes, backed by a new V3AppCred
Authenticator (identity/v3appcred.go).

Goose previously only supported username+password auth (v2/v3) and
EC2-style access/secret key pairs; there was no way to authenticate
with an OpenStack application credential (id+secret), a distinct
Keystone auth method with its own request shape and no explicit
project scope (the credential is already scoped at creation time;
Keystone rejects an explicit scope alongside it).

Credentials gains ApplicationCredentialID/ApplicationCredentialSecret
fields, and CredentialsFromEnv reads them from the standard
OS_APPLICATION_CREDENTIAL_ID/OS_APPLICATION_CREDENTIAL_SECRET env
vars, consistent with the existing OS_* variables it already reads.

Adds a fake Keystone v3 test service
(testservices/identityservice/v3appcred.go) and a test suite
(identity/v3appcred_test.go) covering a full auth round-trip, invalid
secret, missing id/secret, and that no scope is ever put on the wire
even if the caller sets TenantName/Domain by mistake.
newClient() only special-cased AuthUserPassV3 for Keystone's v3
'/auth/tokens' suffix; every other mode, including the new
AuthApplicationCredentialV3, fell through to the default '/tokens'
(Keystone v2) suffix. The v3 application-credential request was
reaching the wrong endpoint entirely (and would 404 against a real
v3-only Keystone), never exercised by the identity-package tests
since those call V3AppCred.Auth() directly with a pre-built URL,
bypassing this client-level suffixing.

Found via a consumer's (spread) end-to-end smoke test that drives
the full client.NewClient(...).Authenticate() path instead of just
the Authenticator in isolation.
time.Time's UnmarshalJSON requires strict RFC3339 (trailing Z or
numeric offset). Keystone's response to application-credential auth
on at least one deployment omits that suffix on expires_at/issued_at
(e.g. "2026-10-08T19:27:05.092894", no Z), which made authentication
fail outright even though these two fields are never read afterwards
in v3KeystoneAuth's returned AuthDetails.

Add flexibleTime: try RFC3339Nano first, fall back to the same layout
without a timezone offset (assumed UTC) if that fails.
@SimonRichardson SimonRichardson left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Comment (1 issue, 1 suggestion)

Critical

  1. None.

Warnings

  1. identity/identity.go:221 — Make CompleteCredentialsFromEnv recognise application-credential authentication. It still treats User and Secrets as required because only the two new application-credential fields are tagged optional, so a standard environment containing only OS_AUTH_URL, OS_APPLICATION_CREDENTIAL_ID, and OS_APPLICATION_CREDENTIAL_SECRET fails validation before V3AppCred.Auth can run. Add mode-aware completion/validation that requires the appropriate alternative credential set without weakening the existing username/password checks, and cover that environment-only path.

Suggestions

  1. identity/v3userpass.go:171 — Add a regression test that authenticates from a token response whose issued_at and expires_at omit a timezone. The fake service serialises time.Now() in RFC3339 form, so the present app-credential tests never execute the new ParseInLocation fallback.

Architecture and Alternative Approaches

  • Keep the shared v3 request and response handling as the common boundary; an authentication-mode-aware credentials validator is sufficient and avoids duplicating environment parsing in V3AppCred.

Looks Good

  • V3AppCred.Auth rejects incomplete application credentials before making a request.
  • The request deliberately omits project scope, matching Keystone application-credential semantics.
  • The client selects the v3 token endpoint for the new mode.

Reviewed by lee-van-cleef[bot]

CompleteCredentialsFromEnv treated User/Secrets as always-required,
so a standard environment containing only OS_AUTH_URL,
OS_APPLICATION_CREDENTIAL_ID, and OS_APPLICATION_CREDENTIAL_SECRET
failed validation before V3AppCred.Auth ever ran. Application
credentials carry no username/password; skip the User/Secrets
check when either application-credential field is present, leaving
the existing username/password/keypair validation unchanged.

Also add a regression test for the flexibleTime no-timezone
fallback: the fake V3AppCred service always serialises expires_at/
issued_at via time.Time (always RFC3339, always a trailing Z), so
the existing app-credential tests never exercised the
ParseInLocation fallback added in 3e75941. Serve a handwritten raw
response instead to cover that path end to end.

Addresses review feedback from @SimonRichardson on PR go-goose#109.
@wallyworld wallyworld left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you - let's fix the warning before landing though.

@simonepelosi
Copy link
Copy Markdown
Contributor Author

Thanks for the review, @wallyworld the warning should be fixed

@SimonRichardson
SimonRichardson merged commit a3a9f66 into go-goose:v5 Oct 16, 2026
2 checks passed
simonepelosi added a commit to simonepelosi/spread that referenced this pull request Oct 16, 2026
goose v5.2.0 ships the application-credential auth that this branch
used to get from a fork (go-goose/goose#109). Require the release and
drop the replace directive that pinned github.com/simonepelosi/goose.

The goose API spread uses is unchanged: the other goose packages are
identical to the pinned fork commit. v5.2.0 also accepts Keystone token
timestamps without a timezone offset, which some deployments return for
application-credential tokens.
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.

3 participants

0