Skip to content

Satellite Authentication on /satellites/sync Endpoint #236

@bupd

Description

@bupd

Context

Satellites send heartbeat/status reports to Ground Control via POST /satellites/sync. This endpoint should validate that requests come from legitimate registered satellites.

Current State

Satellite side (internal/state/reporting_process.go:120-154):

  • Sends POST to /satellites/sync with JSON body
  • Only sets Content-Type: application/json header
  • No authentication credentials sent

GC side (ground-control/internal/server/satellite_handlers.go:358):

  • Looks up satellite by name field from request body
  • If satellite exists in DB, processes the request
  • No credential validation

Security Issue: Anyone who knows a satellite name can impersonate it and send fake status reports. The route is public (not under protected subrouter).

Expected Behavior

Option A: Robot Account Credentials (ZTR)

  • Satellite includes robot account credentials (from ZTR) in Authorization header
  • GC validates credentials against stored robot account for that satellite
  • Return 401 if credentials invalid or don't match satellite

Option C: SPIFFE/SPIRE (mTLS with X.509-SVID)

Preferred for zero-trust environments. Two sub-options based on SPIFFE spec:

C1: X.509-SVID with mTLS (recommended)

  • Satellite obtains X.509-SVID from local SPIRE agent via Workload API
  • Satellite establishes mTLS connection to GC using X.509 certificate
  • GC validates certificate against SPIFFE trust bundle
  • SPIFFE ID extracted from certificate identifies the satellite
  • No additional header needed - identity proven via TLS handshake

C2: JWT-SVID (when mTLS not possible)

  • Used when L7 proxy/load balancer sits between satellite and GC
  • Satellite obtains JWT-SVID from SPIRE agent via Workload API
  • JWT passed in Authorization: Bearer <jwt-svid> header
  • GC validates JWT signature against SPIFFE trust bundle
  • SPIFFE ID extracted from JWT sub claim
  • Note: JWT-SVIDs are susceptible to replay attacks, use short TTLs

SPIFFE ID format: spiffe://trust-domain/satellite/<satellite-name>

Value

  • Prevents satellite impersonation
  • Ensures heartbeat data integrity
  • Foundation for satellite revocation
  • Required for security compliance
  • SPIFFE option enables zero-trust architecture

Changes to be Made

  • Satellite: Add authentication header to sync requests
  • GC: Add satellite authentication middleware
  • GC: Validate credentials on /satellites/sync
  • Return 401 with clear error for invalid credentials
  • Log authentication failures
  • (SPIFFE) Configure SPIRE trust bundle in GC
  • (SPIFFE) Implement SVID validation
Files to Modify

Satellite:

  • internal/state/reporting_process.go (add auth header)

Ground Control:

  • ground-control/internal/server/middleware.go (satellite auth middleware)
  • ground-control/internal/server/routes.go (apply middleware)
  • ground-control/internal/server/satellite_handlers.go
SPIFFE Resources

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions