auth-yes/tasks/new/2026-0827.05.gem.feat.mesh.spiffe-workload-api-live-harness-1043.md

3.7 KiB

TASK METADATA

  • Target Files:
    • spire_ffi/src/lib.rs
    • spire_ffi/Cargo.toml
    • server/spire.ts
    • server/routes/rpc.ts
    • server/tests/spire_workload.test.ts
    • infra/spire/docker-compose.test.yml
  • Core Objective: Establish a comprehensive integration harness and automated testing pipeline for the Rust SPIFFE/mTLS FFI crate (spire_ffi/), enabling live X.509 SVID validation and ConnectRPC mutual TLS attestation against a containerized SPIRE agent.
  • Dependencies:
    • Rust toolchain (cargo, rustc).
    • Deno FFI (--allow-ffi).
    • Containerized SPIRE Server & Agent in infra/spire/.
  • Additional Important Notes:
    • Must provide a seamless mock fallback for standard development environments when libspire_ffi.so is not built, while enforcing strict validation in mesh-enabled environments.

2. Architectural Considerations & Risks

Risks

  1. Native Dynamic Library Portability: C dynamic libraries (.so, .dylib, .dll) compiled on one architecture/OS cannot run on others without cross-compilation.
    • Mitigation: Keep server/spire.ts resilient with an explicit graceful fallback mock layer when libspire_ffi is missing. Provide a dedicated task script (deno task build:ffi) that compiles spire_ffi locally using cargo build --release.
  2. Workload API Unix Domain Socket Timeouts: If the SPIRE agent daemon restarts or socket permissions change, FFI calls to fetch X.509 SVIDs could block or hang worker threads.
    • Mitigation: Enforce non-blocking socket reads with strict timeouts (e.g. 500ms) inside Rust FFI functions before returning to Deno.

Alternatives

  • Pure TypeScript gRPC Client for SPIRE Workload API: We considered writing a pure TypeScript gRPC client. However, SPIRE's Workload API communicates over Unix Domain Sockets with strict OS-level credential passing (SO_PEERCRED), which is far more performant and natively handled via the official spire-api-sdk crate in Rust.

3. Proposed Implementation

Phase 1: Rust FFI Hardening (spire_ffi/src/lib.rs)

  1. Enhance spire_ffi:
    • Implement fetch_x509_svid(socket_path: *const c_char, timeout_ms: u32) -> FfiResult.
    • Implement validate_spiffe_id(client_cert_der: *const u8, cert_len: usize, expected_spiffe_id: *const c_char) -> bool.
    • Ensure all string buffers and error structures are safely allocated and freed across the FFI boundary (free_ffi_string).

Phase 2: Deno FFI Binding & Fallback Layer (server/spire.ts)

  1. Load dynamic library:
    • Search ./libspire_ffi.so, ./spire_ffi/target/release/libspire_ffi.so, and system library paths.
    • If missing, log a warning and activate the hermetic mock provider for local unit testing.
  2. Expose high-level TypeScript API:
    • getWorkloadSvid(socketPath?: string): Promise<{ spiffeId: string, certChain: Uint8Array, privateKey: Uint8Array }>
    • verifyClientSpiffeId(cert: Uint8Array, expectedId: string): boolean

Phase 3: ConnectRPC Integration & Test Harness

  1. In server/routes/rpc.ts:
    • Bind incoming ConnectRPC service requests to verifyClientSpiffeId when running behind mTLS proxies.
  2. In infra/spire/docker-compose.test.yml:
    • Add minimal SPIRE Server & Agent test configuration with a registered test workload entry (spiffe://system.local/auth-yes-tester).
  3. In server/tests/spire_workload.test.ts:
    • Test live X.509 SVID acquisition, parsing, and ConnectRPC authorization against the running test SPIRE container.

Phase 4: Quality Gates

  1. Run cargo test in spire_ffi/.
  2. Run deno fmt, deno task lint, deno task check, and deno test -A --no-check.