feat: add live GitHub OIDC end-to-end test for AssumeRoleWithWebIdentity

Add IAMAssumeRoleWithWebIdentity_github_oidc_live, the only web-identity test that exercises AssumeRoleWithWebIdentity against a real external OIDC provider end-to-end: GitHub Actions' own issuer, with real discovery-document fetch, JWKS fetch, RS256 signature verification, claims mapping, and session credential issuance. Every other web-identity test in the suite uses a fake token that never reaches real signature verification. The test registers a throwaway OIDC provider and trust role scoped to this repo (via a distinct test audience and repo-scoped sub condition), fetches a real ID token from GitHub's runtime endpoint, assumes the role, and confirms the issued session credentials work with a follow-up GetCallerIdentity call. It cleans up the role and provider unconditionally and skips itself when run outside a GitHub Actions job with id-token: write permission (e.g. local runs or fork PRs, where GitHub downgrades OIDC permissions to read-only).

Add functional-iam-oidc.yml to run this test in CI on push to main and on same-repo pull_request runs, isolated from the full iam suite since it's the only test needing id-token: write.

Add a SKIP counter and skipF() alongside the existing runF/passF/failF, and report it in the final RAN/PASS/FAIL summary, so a test opting out via skipF() (as this one does when OIDC env vars aren't present) is visible instead of silently absent from the count.
This commit is contained in:
niksis02
2026-08-15 17:49:06 +04:00
parent 4756b4d236
commit eeff64c255
5 changed files with 345 additions and 6 deletions
+88
View File
@@ -0,0 +1,88 @@
name: IAM functional tests (GitHub OIDC live)
# This workflow exercises AssumeRoleWithWebIdentity against a REAL external
# OIDC identity provider (GitHub Actions' own OIDC issuer) - the one publicly
# reachable, free IdP available from inside our own CI job, so no self-hosted
# IdP container is needed.
#
# Trigger stays plain `pull_request` (never pull_request_target or
# workflow_run) plus `push` to main. On a pull_request run, GitHub itself
# downgrades GITHUB_TOKEN/OIDC permissions to read-only whenever the PR
# comes from a fork - regardless of what this file requests - so
# ACTIONS_ID_TOKEN_REQUEST_URL/ACTIONS_ID_TOKEN_REQUEST_TOKEN simply won't
# exist in that case and the test below skips itself. That's the actual
# security boundary here: a hostile fork-PR author cannot use their own PR
# to mint a token scoped to this repo's identity through this workflow. Only
# a same-repo (non-fork) pull_request run, or a push to main, gets real
# credentials and actually exercises the live OIDC flow.
permissions:
contents: read
id-token: write
on:
pull_request:
push:
branches: [main]
jobs:
build:
name: RunIAMGitHubOIDCTest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "stable"
id: go
- name: Get Dependencies
run: |
go mod download
- name: Build
run: |
make testbin
- name: Run GitHub OIDC live web-identity test
run: |
set -Eeuo pipefail
IAM_PID=""
cleanup() {
local status=$?
trap - EXIT
if [[ -n "$IAM_PID" ]] && kill -0 "$IAM_PID" 2>/dev/null; then
kill "$IAM_PID" 2>/dev/null || true
fi
if [[ -n "$IAM_PID" ]]; then
wait "$IAM_PID" 2>/dev/null || true
fi
exit "$status"
}
trap cleanup EXIT
mkdir -p /tmp/iam-oidc
./versitygw --health /healthz -p :7078 -a user -s pass iam --dir /tmp/iam-oidc &
IAM_PID=$!
ready=""
for _ in {1..50}; do
if curl --fail --silent --max-time 1 http://127.0.0.1:7078/healthz >/dev/null 2>&1; then
ready=1
break
fi
if ! kill -0 "$IAM_PID" 2>/dev/null; then
echo "IAM API server stopped before becoming ready" >&2
exit 1
fi
sleep 0.2
done
if [[ -z "$ready" ]]; then
echo "timed out waiting for IAM API server" >&2
exit 1
fi
./versitygw test -a user -s pass -e http://127.0.0.1:7078 IAMAssumeRoleWithWebIdentity_github_oidc_live