Feature/auth refactor - #135
Open
stephen-dixon wants to merge 14 commits into
Open
stephen-dixon wants to merge 14 commits into
stephen-dixon wants to merge 14 commits into
Conversation
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 37429956 | Triggered | Generic CLI Secret | b472fc5 | test/e2e/keycloak/run_matrix.sh | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Collaborator
Author
|
@jholloc do you have access to the gitguardian dash to resolve the spurious issue raised? |
stephen-dixon
marked this pull request as ready for review
September 18, 2026 15:58
This branch has not been deployed
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.
TLS transport encryption and OIDC bearer-token authentication
Read
docs/authentication.mdfirst — it is the reference for everything below, anddocs/authentication-deployment.mdis the runbook. Between them they cover the behaviourbetter than this description can.
At a glance
ENABLE_AUTH=OFF(the default) nothing changes for any existing deployment.UDA_AUTH_TOKENwith a token it obtained elsewhere. The server verifies itonce, at the handshake, against the issuer's published keys, then applies a claim
policy deciding whether that bearer is allowed in. Verified claims reach plugins.
whichever is shorter. On expiry the server returns 706 and closes the connection.
JSON line each in
refused_requests.log.does not send the token at all. A v10 client hitting an auth-enabled v11 server is
refused with 700 and told to upgrade.
find_package, falling back to a pinned download. picojson was removed entirely.Scale: ~9,800 lines across source, tests and docs. Roughly a third is tests.
1. "Does this affect me if I don't use it?"
ENABLE_AUTH=OFFis the default; auth code is not compiled in.truncate. The server forks per connection, so the old default meant every new connection
wiped the previous one's logs. They now grow and need rotation.
UDA_LOG_MODE=wrestores the old behaviour.
re-received per request and was re-allocated without release).
IDAM_PLUGIN_INTERFACEwas left uninitialised at five sites, so a plugincalling
authPayloadValue()could read an indeterminate pointer.2. "How does a request get authenticated?"
Path:
udaClient.cpp→xdrlib.cpp→handshake_auth.cpp→oauth_authentication.cppUDA_AUTH_TOKENis set.xdr_authentication_blockcaps the payload at 16 KB before allocating.check_oidc_client_authgates: protocol version, block present, no embedded NULs, thenverification.
authenticate()does discovery → JWKS (cached, TTL 300s) → signature → issuer →audience → claim policy. Algorithm is pinned by config, never taken from the token's
own
algheader.kidtriggers one refresh and retry.3. "What stops a bad token getting in?"
exp/nbfalways checked.refuses everything with 701 rather than accepting any valid token the issuer ever minted.
UDA_SERVER_OIDC_POLICY=noneopts out explicitly and warns on every connection.negotiable). CRL checking now covers the whole chain, not just the leaf.
kid),alg: none, tampered signature, malformed tokens.4. "What happens when something is refused?"
706 expired, 707 bad issuer, 708 bad audience, 710–712 TLS.
refused_requests.logwith stage, reason code, peer,per-connection pid, and for TLS the offending certificate's subject and expiry.
UDA_LOG— turning down debuglogging does not switch off the audit trail.
server-side record is the only account of it.
5. "How do plugins use the claims?"
authPayloadValue(key, pi)— flat claim.authPayloadPath(path, pi)— nesting and array indexing, e.g.realm_access.roles[0].authPayloadContains(path, value, pi)— membership.UDA_SERVER_OIDC_REQUIRED_CLAIMS; one shared engine(
claim_access.cpp) backs both, so a policy path and a plugin path mean the same thing.HELP::authorise()demonstrates calling an external authorisation service.HELP::servermetadata()reports compile flags and effective runtime config.6. "Can I see it work?"
demo/oidc/—docker compose up -d --build && ./demo.sh. Keycloak + a UDA server +an authz service, with a guided tour that prints each command before running it.
/uda-usersand gets in; adam is a real,enabled user in
/uda-observerswho authenticates perfectly and is then refused with 705.Authentication is not authorisation.
test/e2e/keycloak/run_matrix.sh— 44 automated checks against a real IdP and a realserver. Can point at an existing deployment with
UDA_EXTERNAL_SERVER=1.Decisions taken (please confirm you agree)
check on the data path.
consumed (the wire format is fixed by protocol version) and dropped.
expplus the sameclock skew used to verify it.
channel to answer a request while also saying "your new token was ignored".
development against a plain-HTTP IdP.
UDA_ALLOW_TOKEN_WITHOUT_TLS=1silences it.Flipping this to a refusal is a one-line change in each of client and server.
UDA_FETCH_DEPENDENCIES=OFFfor air-gapped andpackaging builds.
Deliberately omitted
mitigation.
point at which the server could report which token was actually in scope.
uda-auth-tools— standalone OIDC/TLS diagnostic CLI, to ship separately as a PyPIpackage rather than in this PR.
Needs explicit review
HELP::servermetadata()exposure. Only reachable by authenticated callers when authis on. On an auth-off server it discloses exact version, build date and compile flags to
anyone who can connect. Low severity, but it is the tool you reach for precisely when
auth is the thing that's broken. Decision deferred — accept or restrict.
UDA_SERVER_AUTHENTICATIONset but no policy will see 701 until they set one. Intended, but it is a breaking change
for such a configuration.
Enabling auth while v10 clients remain locks them out with no workaround but upgrading.
.gitguardian.yamldeclares the test realm's published dummy credentials file byfile (not a directory glob, so a real secret added elsewhere is still caught).
Verification
spawned, launchd socket-activated, and containerised.
ssl=ONjob (they previously never ran), the SSL systemtests were gated on a runner not in the matrix and now execute, and the OIDC e2e suite
runs with log collection on failure.