Add OIDC authentication to integration tests#75
Conversation
dcf859a to
55b79f8
Compare
c59b61b to
0ab890a
Compare
c4d005d to
9c35910
Compare
Deploys Dex (OIDC provider) and a Python/ldaptor in-memory LDAP server alongside CTS in the EaaS pipeline and exercises the full mod_auth_openidc → load_openidc_user → get_user_info → query_ldap_groups → has_role auth stack end-to-end. Pipeline changes (.tekton/integration-test-eaas.yaml): - New deploy-openldap task: in-memory LDAP server (ldaptor) serving the cts-builders posixGroup, runs without root on any UID - New deploy-dex task: Dex with TLS (self-signed CA), password connector, static OAuth2 client cts-integration - Updated deploy-cts: AUTH_BACKEND=oidc_or_kerberos, httpd.conf with AuthType oauth20 / OIDCOAuthVerifyJwksUri / OIDCCABundlePath for bearer token validation; SetEnv OIDC_CLAIM_scope scoped to Bearer requests only - Updated run-tests: passes AUTH_BACKEND=oidc_or_kerberos; installs requests; writes Dex CA to /tmp and sets REQUESTS_CA_BUNDLE Test changes (tests/test_integration_api.py): - AuthHTTPClient: HTTPClient subclass that injects Authorization: Bearer - _get_oidc_token(): obtains a real access token from Dex via ROPC grant - _make_ssl_context(): builds an SSLContext from REQUESTS_CA_BUNDLE for use with urllib.request.urlopen - write_http_client fixture: returns AuthHTTPClient under OIDC or plain HTTPClient in noauth mode; pre-existing workflow tests use it - Four new tests (all four explicitly skip when not _is_oidc_backend()): - test_auth_unauthenticated_write_returns_401 - test_auth_builder_can_post_compose - test_auth_unauthorized_user_returns_403 - test_auth_get_endpoints_accessible_without_token Generated-By: OpenCode (google-vertex-anthropic/claude-sonnet-4-6@default)
| export HOME=/tmp | ||
| echo "Installing ldaptor and twisted..." | ||
| python3 -m ensurepip | ||
| python3 -m pip install --target /tmp/ldap-deps --quiet ldaptor twisted |
There was a problem hiding this comment.
I guess this is temporary, but these dependencies would be better pre-baked into a container image.
There was a problem hiding this comment.
That said, I do not know if it is worth it for just those two dependencies.
There was a problem hiding this comment.
This is a good point. The LDAP setup could likely be moved to an image. In fact, the initial attempts were trying to use existing images, but neither really worked in this setup. The image for this setup would not be complicated, but there would be additional overhead about where and how to build it.
For the record, the tried images were:
- glauth - the blocker was that it doesn't support anonymous binds, so all CTS queries were denied
- osixia/openldap - doesn't work under OCP restricted-v2 SCC since the image can not run under random UID
There was a problem hiding this comment.
I think this could be left as a separate cleanup to not blow this PR up even more.
There was a problem hiding this comment.
Regarding how to build them, I suggest using the Containerfile in this repo, along with a PaC Konflux definition to push it to Quay.
The authenticated client only needs to add an extra header, no need to duplicate the whole method. A hook is added that allows subclasses to modify the request before it gets sent. Assisted-By: OpenCode (google-vertex-anthropic/claude-opus-4-6)
Two integration tests are already skipped on non-OIDC run by the fixtures. There's no need to explicitly skip in the test itself too. The test for validating unauthenticated GET request drops the skip too. The behavior makes sense even in noauth mode, GET request should still succeed. The only test that really needs the explicit skip is the unauthenticated POST, which would otherwise fail in noauth mode (the request would be allowed). Assisted-By: OpenCode (google-vertex-anthropic/claude-opus-4-6)
Add OIDC authentication to integration tests
Deploys Dex (OIDC provider) and an in-memory LDAP server (ldaptor) alongside CTS
in the EaaS pipeline and exercises the full
mod_auth_openidc→load_openidc_user→
get_user_info→query_ldap_groups→has_roleauth stack end-to-end.Pipeline changes (
.tekton/integration-test-eaas.yaml)deploy-openldaptask (runs in parallel withdeploy-dexafterprovision-environment): creates aConfigMapwith an in-memory LDAP serverscript (using ldaptor/Twisted) defining two users (
builder/readonly) andtwo groups (
cts-builders/readonly-users), then deploys the server on port1389.
deploy-dextask (parallel withdeploy-openldap): generates aself-signed CA and TLS certificate for Dex, creates a
ConfigMapwith a Dexconfig using the password connector and a static OAuth2 client
(
cts-integration), then deploys Dex on port 5556.deploy-cts:runAfternow includesdeploy-openldapanddeploy-dex. Thects-configConfigMap setsAUTH_BACKEND=oidc_or_kerberos,AUTH_OPENIDC_USERINFO_URI,AUTH_LDAP_SERVER(pointing toopenldap:1389),AUTH_LDAP_GROUPS,ADMINS, andALLOWED_BUILDERS. Thehttpd.confgainsmod_auth_openidcdirectives (OIDCProviderMetadataURL,OIDCOAuthVerifyJwksUri,OIDCClientID/Secret,OIDCRemoteUserClaim,OIDCCABundlePath) and a<RequireAny>block that allows unauthenticatedGET requests while requiring a valid Bearer token for writes.
run-tests: installsrequestsalongsidepytest, retrieves theDex CA certificate, and passes
AUTH_BACKEND=oidc_or_kerberosandDEX_URL=https://dex:5556to the test runner so the auth tests are not skipped.Test changes (
tests/test_integration_api.py)AuthHTTPClient:HTTPClientsubclass that injectsAuthorization: Beareron every request.
_get_oidc_token(): obtains a real access token from Dex via the ROPC grant;used by
auth_http_client_builderandauth_http_client_readonlyfixtures.write_http_clientfixture: returns anAuthHTTPClient(asbuilder) whenOIDC is active, or a plain
HTTPClientin noauth mode. Existing workflow teststhat perform writes are updated to use this fixture.
AUTH_BACKENDis notopenidcoroidc_or_kerberos):test_auth_unauthenticated_write_returns_401– bare POST → 401test_auth_builder_can_post_compose–builderBearer token → 200test_auth_unauthorized_user_returns_403–readonlyBearer token → 403test_auth_get_endpoints_accessible_without_token– unauthenticated GET → 200All pre-existing tests continue to pass unchanged under
AUTH_BACKEND=noauth.