Skip to content

vault: add generic authorizer with jwt auth support#21714

Merged
prashantkumar1982 merged 1 commit intodevelopfrom
codex/vault-gwt-auth-authorizer
Apr 2, 2026
Merged

vault: add generic authorizer with jwt auth support#21714
prashantkumar1982 merged 1 commit intodevelopfrom
codex/vault-gwt-auth-authorizer

Conversation

@prashantkumar1982
Copy link
Copy Markdown
Contributor

@prashantkumar1982 prashantkumar1982 commented Mar 26, 2026

Summary

This adds the Vault auth abstraction needed for gateway-side JWT support while keeping current behavior unchanged because JWT auth remains disabled.

What changed

  • add a generic Authorizer used by both the Vault gateway handler and the Vault capability gateway handler
  • model two first-class auth mechanisms: AllowListBasedAuth and JWTBasedAuth
  • add a shared AuthResult contract and a shared RequestReplayGuard
  • implement JWT auth validation plumbing behind JWTBasedAuth, gated internally and failing closed when disabled
  • rename the old request-authorizer/replay-guard types and files to reflect the new mechanism names

Behavior

  • runtime behavior is unchanged today because JWT auth is still disabled
  • allowlist-based auth remains the active mechanism for existing traffic

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

✅ No conflicts with other open PRs targeting develop

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This file is pretty much just a rename of previous request_authorizer.go file

@trunk-io
Copy link
Copy Markdown

trunk-io bot commented Mar 26, 2026

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@prashantkumar1982 prashantkumar1982 force-pushed the codex/vault-gwt-auth-authorizer branch from 77cda12 to 68f66e2 Compare March 26, 2026 06:43
@prashantkumar1982 prashantkumar1982 requested a review from a team as a code owner March 26, 2026 16:14
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

CORA - Analysis Skipped

Reason: The number of code owners (4) is less than the minimum required (5) and/or the number of CODEOWNERS entries with changed files (3) is less than the minimum required (2).

if a.orgID != "" {
return a.orgID
}
return a.workflowOwner
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Aren't we tying all secrets to the org ID? Or is this just for backwards compat and we're planning to remove it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is for the allowlist based auth.
This is on gateway and on vault node before LinkingService.
So we haven't yet mapped workflowOwner to OrgID.
For old auth, workflowOwner is still the owner for the purpose of the request.
Conversion to orgID will happen later in the stack after auth is done.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For old auth, workflowOwner is still the owner for the purpose of the request.

Isn't that model changing? What happens if wfOwner1 moves from Org X to Org Y - if we don't do that mapping prior, do we prevent wfOwner1 from managing Org X's secrets?

if a.orgID != "" {
return a.orgID
}
return a.workflowOwner
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For old auth, workflowOwner is still the owner for the purpose of the request.

Isn't that model changing? What happens if wfOwner1 moves from Org X to Org Y - if we don't do that mapping prior, do we prevent wfOwner1 from managing Org X's secrets?

if req.Auth == "" {
return a.authorizeAllowListBasedAuth(ctx, req)
}
return a.authorizeJWTBasedAuth(ctx, req)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How are we planning to support m2m tokens in the future? They will likely need to have a different prefix. Is it worthwhile making this change now?

func NewJWTBasedAuth(cfg JWTBasedAuthConfig, limitsFactory limits.Factory, enabled limits.GateLimiter, lggr logger.Logger) (*jwtBasedAuth, error) {
if enabled == nil {
enabled = newVaultJWTAuthEnabledLimiter(limitsFactory, lggr)
func NewJWTBasedAuth(cfg JWTBasedAuthConfig, limitsFactory limits.Factory, lggr logger.Logger, opts ...JWTBasedAuthOption) (*jwtBasedAuth, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We'll need to test the JWKS behaviour on the first call. It's generally good practice to hot-load the JWKS in the background even before a request comes through (i.e. on construction time)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, let me do it in a background thread

)

type ErrJobSpecNoRelayer struct {
type JobSpecNoRelayerError struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What happened here? Did this need to change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was trying to run the linter locally as it runs in CI, and it complained about this error. So I fixed it. Not sure if CI would've complained about it though. But the fix was simple, so just did it.

@prashantkumar1982
Copy link
Copy Markdown
Contributor Author

For old auth, workflowOwner is still the owner for the purpose of the request.

Isn't that model changing? What happens if wfOwner1 moves from Org X to Org Y - if we don't do that mapping prior, do we prevent wfOwner1 from managing Org X's secrets?

@elatoskinas

When an incoming request comes in via old auth flow, this authorizer just authenticates if the calling request was authorized via allowlist, and to which workflowOwner key.
This is then passed into Vault Capability as-is, and that is where the linking service is called to check the correct owning orgID for it. That is where the OrgID gets superceded.
In this authorizer, we don't call the linking service.

@prashantkumar1982
Copy link
Copy Markdown
Contributor Author

#21714 (comment)

@elatoskinas : I don't have more context on m2m tokens.
How will they be different?
In any case, when we support that, it will need to be supported fully at gateway webserver level too first.
Thus I was saying, lets keep that in a separate PR whenever needed.

@elatoskinas
Copy link
Copy Markdown
Contributor

@prashantkumar1982

I don't have more context on m2m tokens.
How will they be different?

Depends on the implementation, but the verification mechanism might change. It's more efficient to pass in the key type e.g. MachineToken <token> rather than relying on this kind of flow:

if verify1() {
  // permit
} else if verify2() {
   // performing verify1() adds extra latency - because we're validating the key of the wrong format
  // permit
}


v.eng.GoTick(services.NewTicker(v.refreshInterval), func(ctx context.Context) {
if err := v.refreshJWKS(ctx); err != nil {
v.lggr.Warnw("periodic JWKS refresh failed", "error", err)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would strongly suggest tracking metrics in production, incl. latency to fetch JWKS & error rate

@prashantkumar1982 prashantkumar1982 force-pushed the codex/vault-gwt-auth-authorizer branch from 5ae8765 to 72f0383 Compare April 2, 2026 16:48
@prashantkumar1982 prashantkumar1982 requested review from a team as code owners April 2, 2026 16:48
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

I see you updated files related to core. Please run make gocs in the root directory to add a changeset as well as in the text include at least one of the following tags:

  • #added For any new functionality added.
  • #breaking_change For any functionality that requires manual action for the node to boot.
  • #bugfix For bug fixes.
  • #changed For any change to the existing functionality.
  • #db_update For any feature that introduces updates to database schema.
  • #deprecation_notice For any upcoming deprecation functionality.
  • #internal For changesets that need to be excluded from the final changelog.
  • #nops For any feature that is NOP facing and needs to be in the official Release Notes for the release.
  • #removed For any functionality/config that is removed.
  • #updated For any functionality that is updated.
  • #wip For any change that is not ready yet and external communication about it should be held off till it is feature complete.

@cl-sonarqube-production
Copy link
Copy Markdown

@prashantkumar1982 prashantkumar1982 added this pull request to the merge queue Apr 2, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 2, 2026
@prashantkumar1982 prashantkumar1982 added this pull request to the merge queue Apr 2, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 2, 2026
@prashantkumar1982 prashantkumar1982 added this pull request to the merge queue Apr 2, 2026
Merged via the queue into develop with commit 61150ff Apr 2, 2026
398 of 400 checks passed
@prashantkumar1982 prashantkumar1982 deleted the codex/vault-gwt-auth-authorizer branch April 2, 2026 21:28
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.

5 participants