feat: OIDC configurable profiles with template support and Kubernetes annotation passing#3917
Open
mjungsbluth wants to merge 8 commits into
Open
feat: OIDC configurable profiles with template support and Kubernetes annotation passing#3917mjungsbluth wants to merge 8 commits into
mjungsbluth wants to merge 8 commits into
Conversation
mjungsbluth
commented
Mar 13, 2026
6923c80 to
dcf487b
Compare
mjungsbluth
commented
Mar 14, 2026
…ing templating Signed-off-by: Magnus Jungsbluth <magnus.jungsbluth@zalando.de> Signed-off-by: magnus-jungsbluth_zse <magnus.jungsbluth@zalando.de>
Signed-off-by: Magnus Jungsbluth <magnus.jungsbluth@zalando.de>
Signed-off-by: magnus-jungsbluth_zse <magnus.jungsbluth@zalando.de>
Signed-off-by: magnus-jungsbluth_zse <magnus.jungsbluth@zalando.de>
Signed-off-by: magnus-jungsbluth_zse <magnus.jungsbluth@zalando.de>
Signed-off-by: magnus-jungsbluth_zse <magnus.jungsbluth@zalando.de>
3394b0e to
c24bece
Compare
Signed-off-by: magnus-jungsbluth_zse <magnus.jungsbluth@zalando.de>
f943163 to
0749e54
Compare
mjungsbluth
commented
Apr 24, 2026
| } | ||
|
|
||
| mu.Lock() | ||
| lastRedirectURI = redirectURI |
Collaborator
Author
There was a problem hiding this comment.
This should be rather set with a test fixture (i.e. the test case should state which redirect_uri is configured. Then the redirect_uri derived from the OIDC profile needs to match.
- Fix filter ordering: injectAnnotateFilters now runs after ic.annotationFilters and default-filter prepends so that annotate() filters are at the head of the chain and their values are visible to downstream filters such as oauthOidc* profile filters. Add a fixture that exercises the combined zalando.org/skipper-filter + annotation-injection path to protect the ordering going forward. - Validate profiles at startup: OidcProfile.Validate() is now called in oidcProfilesMap() so malformed templates, missing IdpURL, and template expressions inside IdpURL are caught at process start rather than on the first request. The IdpURL-static check is also moved into Validate() itself, removing the duplicate in createProfileFilter(). - Explicit redirect_uri in e2e tests: createFlexOIDCServer now returns a *flexOIDCServer struct with a setExpectedRedirectURI method. Test cases that go through the full auth-code flow set the expected redirect_uri derived from proxy.URL after the proxy is started, so the OIDC server actively rejects a wrong callback URL instead of silently accepting whatever comes in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Usage
Define profiles
Pass named profiles via
-oidc-profiles(inline YAML) or the new-oidc-profiles-fileflag (path to a YAML file; the two flags are mutually exclusive):skipper -oidc-secrets-file /path/to/secrets \ -oidc-profiles-file /path/to/profiles.yamlAll fields except
idp-urlsupport Gotext/templateexpressions resolved at request time:{{.Request.Host}}{{index .Annotations "key"}}annotate()filterclient-idandclient-secretalso accept the existingsecretRef:prefix and for client-secret this is the secure default.Reference profiles in routes
Use
profile:<name>as the first argument to anyoauthOidc*filter. Claims are still passed as a second argument:Multi-tenant with Kubernetes annotations
Define a template-driven profile:
Start Skipper with the new
-kubernetes-annotations-to-route-annotationsflag to automatically inject Kubernetes resource annotations asannotate()filters into generated routes:An optional
-kubernetes-annotations-to-route-annotations-prefixprepends a string to each key in the generatedannotate()call (no separator added; K8s annotation lookup key is unchanged):# annotation "oidc/client-id" produces annotate("k8s:oidc/client-id", value) skipper -kubernetes-annotations-to-route-annotations=oidc/client-id \ -kubernetes-annotations-to-route-annotations-prefix=k8s:Annotate Kubernetes Ingress or RouteGroup resources:
New flags
-oidc-profiles-oidc-profiles-file.-oidc-profiles-file-oidc-profiles.-kubernetes-annotations-to-route-annotationsannotate()filters into routes generated from Kubernetes resources.-kubernetes-annotations-to-route-annotations-prefixannotate()filter calls (no separator added).Architecture
filters/auth/oidcprofile.go(new) —OidcProfilestruct with YAML tags;tokenOidcProfileFilterwhich resolves Gotext/templatefields at request time and caches fully-constructedtokenOidcFilterdelegates in async.Mapkeyed by SHA-256 hash of resolved parameters. Provider discovery runs once atCreateFiltertime so it is shared across all delegates.filters/auth/oidc.go—CreateFilterdetects theprofile:prefix and delegates tocreateProfileFilter, which looks up the profile, discovers the provider, and returns atokenOidcProfileFilter.OidcOptionsgains aProfiles map[string]OidcProfilefield.dataclients/kubernetes/annotations.go— newinjectAnnotateFilters(annotations, keys, prefix, route)helper; prependsannotate(prefix+key, value)filters for each configured key present on the resource. Called from both Ingress (ingressv1.go) and RouteGroup (routegroup.go) conversion paths.config/config.go/skipper.go— four new flags wired throughskipper.Options → kubernetes.Options / auth.OidcOptions.