92 lines
3.7 KiB
Markdown
92 lines
3.7 KiB
Markdown
# 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`.
|