Skip to content

OIDC Architecture Vision: Local-First with Optional Enterprise Bridge #119

@bordumb

Description

@bordumb

Summary

Define the long-term architecture for OIDC-based machine identity in Auths. The vision: local-first by default (no external service required), with optional bridge for enterprise policy/audit. This resolves the architectural tension between self-hosted resilience and centralized control.

Problem Statement

Two competing approaches exist:

  1. Local-First (fn-85): Validate OIDC tokens locally, create ephemeral identities, sign in-process. No external dependency.

    • Pro: Always works, offline-capable, fast, simple
    • Con: No centralized policy engine or audit trail
  2. Bridge-Required: All OIDC validation happens at centralized service (auths-oidc-bridge).

    • Pro: Single source of truth for policy, audit, compliance
    • Con: Service outage = broken CI, network latency, requires infrastructure

Current state: fn-85 is local-first, but auths-oidc-bridge exists (written 2 months ago) and could compete with it.

Proposed Vision (2-Year)

Default Path: Local-First (90% of Users)

```
auths init --profile ci
→ Auto-detect platform (GitHub Actions, GitLab CI, CircleCI)
→ Acquire OIDC token
→ Validate locally (JWKS cached, subsequent runs offline)
→ Generate ephemeral Ed25519 keypair (in-memory)
→ Create KERI identity bound to OIDC token
→ Sign commits/artifacts
→ Attestation stored in git (verifiable forever, no external service)
```

Properties:

  • No network call after first JWKS fetch
  • Works offline (except token acquisition)
  • No infrastructure required
  • Developers get immediate value

Enterprise Path: Optional Bridge (10% of Users)

```
auths init --profile ci --bridge https://auths-policy-server.internal
→ Same as local-first, BUT
→ After signing, submit attestation to bridge (async, non-blocking)
→ Bridge evaluates policy:
- Reject signing from untrusted repositories
- Enforce timestamp from hardware security module (HSM)
- Check revocation list for compromised identities
→ Bridge logs audit trail (SOC2, FedRAMP compliance)
→ Verifiers can query bridge for policy decisions
```

Properties:

  • Opt-in, not required
  • Non-blocking (doesn't slow down CI)
  • Only for teams with strict compliance needs
  • Can be self-hosted or cloud-hosted

Architecture Comparison

Aspect Local-First Bridge-Required Hybrid (Recommended)
Availability Always works Service outage breaks CI Always works
Latency Fast +100ms network call Fast by default
Complexity Moderate High Moderate
Offline Capable ✓ Yes ✗ No ✓ Yes
Policy Engine Basic (policy library) Centralized Both (distributed + centralized)
Audit Trail Per-repo (git-native) Central (bridge) Both

Hybrid wins for enterprise adoption.

Technical Approach

Phase 1: Ship fn-85 Local-First

  • Implement local OIDC validation (JWT decode, JWKS cache, signature verification)
  • Ephemeral identity creation (Ed25519 in-memory, KERI inception, OIDC binding)
  • Git-native attestation storage
  • Works for 80% of users immediately

Phase 2: Extract Bridge Code to Libraries (v1.1)

  • Extract `verify_github_token()` from auths-oidc-bridge → auths-infra-http
  • Move `GitHubOidcClaims` struct → auths-jwt
  • Move `JwksClient` pattern → shared JWKS cache trait
  • This code is already written and tested; reuse it

Phase 3: Reposit Bridge as Optional Service (v2)

  • Rename auths-oidc-bridge → `auths-policy-server`
  • Document as enterprise tier (compliance, audit, policy)
  • Provide Helm charts / Docker images for self-hosted deployment
  • Provide cloud-hosted version (auths-cloud SaaS)
  • Make it completely optional (CI works perfectly without it)

Phase 4: Bridge Enhancements (v2+)

  • HSM-backed signing for timestamps (RFC 3161)
  • Central revocation list for ephemeral identities
  • Policy DSL for repo/branch/actor constraints
  • Audit trail (immutable ledger of all signings)
  • SPIFFE/SVID integration (for Kubernetes)

What to Do with Existing Bridge Code

Don't delete it. Preserve and reuse:

  • `github_oidc.rs`: JWKS caching + circuit breaker → extract to shared library
  • `issuer.rs`: Token issuance logic → keep as bridge service
  • `policy_adapter.rs`: Policy evaluation → extend for v2
  • Tests: Already comprehensive; reuse as validation

Recommendation: Archive bridge as reference implementation, extract libraries, keep codebase as v2 foundation.

Success Criteria

  • fn-85 ships (local-first, zero bridge dependency)
  • Developers can sign commits in CI without external service
  • `auths verify-commit` works offline (OIDC binding in attestation)
  • Bridge code extracted to reusable libraries (auths-infra-http, auths-jwt)
  • Bridge documented as optional enterprise layer (not required)
  • No breaking changes between local-first and bridge-optional paths
  • Bridge can be enabled/disabled at job level (`--bridge` flag)
  • Performance: local path is faster than bridge path (local < 10ms, bridge +100ms)

Architectural Principles

  1. Decentralized by default: Auths works offline, without external services
  2. Centralized control optional: Bridge is a bolt-on for enterprises, not core
  3. Git-native verification: Attestations are verifiable using only git, forever
  4. Fail-open gracefully: If bridge is unavailable, signing continues (audit is optional, not blocking)

Related Issues

Timeline

  • v1 (fn-85): Local-first only, ship immediately (Q2)
  • v1.1: Extract bridge code to libraries, document (Q2)
  • v2: Reposit bridge as optional enterprise service (Q3)
  • v2+: HSM, revocation, SPIFFE, audit trail (Q4+)

Decision Point: Accept local-first as the default path, position bridge as optional enterprise layer. This unblocks fn-85 shipping and clarifies the auths-oidc-bridge's long-term role.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrustPull requests that update rust code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions