Skip to content

test(e2e): add Kerberos/SPNEGO end-to-end test harness#755

Closed
aborovsky wants to merge 22 commits into
nextfrom
kerberos-e2e
Closed

test(e2e): add Kerberos/SPNEGO end-to-end test harness#755
aborovsky wants to merge 22 commits into
nextfrom
kerberos-e2e

Conversation

@aborovsky

@aborovsky aborovsky commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Kerberos/SPNEGO E2E Test Harness

This PR adds a self-contained Docker Compose E2E test harness that validates Kerberos/SPNEGO authentication through the bright-cli repeater, exercising the changes in:

What's included

kerberos-e2e/
├── docker-compose.yml             # 3-service stack on a bridged 172.30.0.0/24 network
├── test.sh                        # 8-step smoke-test runner
├── kdc/                           # MIT Kerberos KDC (realm EXAMPLE.COM)
├── httpd/                         # Apache httpd + mod_auth_gssapi (SPNEGO endpoint)
└── repeater/                      # bright-cli built from feat/kerberos-auth
    ├── Dockerfile                  # builds node-libcurl from source with GSSAPI via vcpkg
    ├── gen-vcpkg-json.js           # generates vcpkg.json with gssapi feature injected
    ├── check-gssapi.js             # build-time sanity check for Kerberos in libcurl
    └── kerberos-integration-test.ts  # full E2E integration test via HttpRequestExecutor

Test results (all passing ✅)

[1/8] Build & start Docker Compose stack              PASS
[2/8] Verify GSS-API support in node-libcurl          PASS  (mit-krb5/1.22.1 linked)
[3/8] kinit inside KDC container                      PASS  (ticket issued)
[4/8] Direct curl --negotiate baseline                PASS  (non-blocking)
[5/8] Connection: close regression check              PASS  (not found in bundle — fixed or refactored)
[6/8] Full E2E: HttpRequestExecutor SPNEGO → HTTP 200 PASS  ← actual auth path confirmed
[7/8] CURLGSSAPI_DELEGATION_FLAG regression           PASS  (BUG DOCUMENTED: value=1, should=2)
[8/8] Repeater platform registration                  SKIP  (requires BRIGHT_TOKEN + REPEATER_ID)

Step 6 — Full E2E integration test

kerberos-integration-test.ts runs inside the repeater container via ts-node and exercises the exact code path changed by PR #751:

HttpRequestExecutor (kerberos.enabled=true, credentials=scanner@EXAMPLE.COM:ScannerPass1)
  → shouldApplyKerberos() → curl.setOpt('HTTPAUTH', CURLAUTH_NEGOTIATE)
    → libcurl GSSAPI handshake (mit-krb5/1.22.1)
      → Apache httpd mod_auth_gssapi (Require valid-user)
        → HTTP 200 ✅

Apache returns 401 on any SPNEGO failure with Require valid-user. Getting HTTP 200 is definitive proof the full authentication chain works end-to-end.

Key build findings

  • vcpkg builds static libs on Linux (x64-linux triplet). Linking only -lcurl leaves GSSAPI symbols unresolved; fixed by using pkg-config --static libcurl for all transitive link flags.
  • scripts/vcpkg-common.js exits immediately on non-Windows; the entire npm install/preinstall hook chain is a no-op on Linux. All vcpkg work is done manually in the Dockerfile.
  • TypeScript must be compiled explicitly (npm run build:dist) after node-pre-gyp; --ignore-scripts skips it.
  • The native .node binary is excluded from npm pack; must be copied manually after installing the tarball with --ignore-scripts.
  • GssapiAllowedMech directive is not available in the Ubuntu 22.04 version of mod_auth_gssapi; removed (default behavior accepts SPNEGO).

Documented bugs in PR #751

# Severity Description
1 High CURLGSSAPI_DELEGATION_FLAG = 1 (PolicyFlag) — should be 2 (DelegationFlag). --kerberos-delegation silently uses policy-gated delegation.
2 Medium Connection: close was being injected for all requests (not confirmed in current bundle — may be refactored).

Running the tests

cd kerberos-e2e
bash test.sh

# With platform registration (step 8):
BRIGHT_TOKEN=<token> REPEATER_ID=<id> bash test.sh

opencode and others added 19 commits June 2, 2026 10:16
Self-contained Docker Compose environment for validating Kerberos/SPNEGO
authentication in the bright-cli repeater (PR #751).

Stack:
- kdc/     MIT krb5 KDC — creates EXAMPLE.COM realm, principals, keytab
- httpd/   Apache httpd + mod_auth_gssapi — SPNEGO-protected /protected endpoint
- repeater/ bright-cli built from feat/kerberos-auth with @brightsec/node-libcurl
           overridden to feat/gssapi-support (node-libcurl PR #19, unmerged)
           which compiles libcurl with GSSAPI via vcpkg

test.sh runs 7 automated steps:
  1. Stack startup + KDC healthcheck
  2. GSS-API present in Curl.getVersion() output
  3. kinit smoke test (ticket acquisition)
  4. Direct curl --negotiate baseline against httpd
  5. Regression: Connection: close not injected for Kerberos requests
  6. Regression: CURLGSSAPI_DELEGATION_FLAG = 2 (unconditional), not 1 (policy)
  7. Repeater platform registration (optional, requires BRIGHT_TOKEN + REPEATER_ID)

Depends on:
  #751
  NeuraLegion/node-libcurl#19
typedoc-plugin-ga@1.1.1 requires typedoc@^0.27.x but
feat/gssapi-support has typedoc@0.28 as a dev dep.
This conflict is dev-only and does not affect the native
C++ build or the packed tarball.
- Switch to Node.js 22 (node-libcurl feat/gssapi-support requires >=22.14)
- Use --ignore-scripts on npm install to skip Windows-only vcpkg-setup.js
- Manually generate vcpkg.json: substitute version/OpenSSL placeholders
  and inject 'gssapi' feature (absent from vcpkg.template.json)
- Run vcpkg install --triplet x64-linux to compile libcurl with GSSAPI
- Build native addon via node-pre-gyp with explicit --curl_include_dirs /
  --curl_libraries flags (bypasses curl-config entirely)
- Add LD_LIBRARY_PATH for vcpkg_installed shared libs
- Verify GSS-API present in Curl.getVersion() before packing
Docker parser treats bare words at line-start inside RUN as Dockerfile
instructions.  Extract the two multi-line Node.js snippets into
gen-vcpkg-json.js and check-gssapi.js, COPY them in, and call them from
single-line RUN commands.
openldap requires autoconf/automake/libtool (not installed in the
build container); gsasl would have the same issue.  Neither feature is
needed for SPNEGO/Kerberos E2E testing, so exclude them alongside sspi.
libunistring (idn2 dep) and other vcpkg autotools-based ports require
autoconf, autoconf-archive, automake, and libtool to be present.
@aborovsky aborovsky marked this pull request as ready for review June 2, 2026 11:59
aborovsky added 3 commits June 3, 2026 12:35
…Executor

Exercises the actual code path changed by PR #751:
  HttpRequestExecutor (kerberos: true, credentials: scanner@EXAMPLE.COM:ScannerPass1)
    → libcurl CURLAUTH_NEGOTIATE (HTTPAUTH=4)
      → mit-krb5 GSSAPI handshake
        → Apache httpd mod_auth_gssapi (Require valid-user)
          → HTTP 200

Previously test.sh only validated build-time artifacts and static analysis.
This new step confirms the end-to-end authentication path works at runtime.
kerberos-integration-test.ts uses Docker-context relative imports
(./src/RequestExecutor/...) that do not exist at the repo root.
Excluding kerberos-e2e/ from the root tsconfig prevents webpack and
ts-jest from trying to compile it during the main build and unit test jobs.
tsconfig.build.json has its own exclude array that does not inherit
from tsconfig.json, so the previous fix did not cover the webpack build.
Both tsconfig files now exclude kerberos-e2e/.
@aborovsky aborovsky marked this pull request as draft June 3, 2026 13:22
@aborovsky aborovsky closed this Jun 10, 2026
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.

1 participant