Transport Security Model
| Property | Value |
|---|---|
| Controls | SID-TRANS-01, SID-AUTH-04, SID-CRYPTO-03 |
| EUDI Requirements | WIN-8.4.1-Sec-01 (wallet instance protection), WIN-8.4.1-Sec-06 (transport security) |
| ISO 27001 | A.5.14, A.8.20, A.8.21 |
Purpose
This document describes the transport security mechanisms across the SIROS ID platform, covering TLS configuration, channel authentication, SSRF protection, and storage differentiation. It addresses the finding that TLS and JWT-based transport exist but mutual authentication and storage protection models were not formally documented.
TLS Configuration
Server-Side TLS
| Component | Min Version | Cipher Suites | Configuration |
|---|---|---|---|
| go-wallet-backend | TLS 1.2 (configurable to 1.3) | Go stdlib defaults | tls.cert_file, tls.key_file, tls.min_version |
| facetec-api | TLS 1.2 (Go default) | Go stdlib defaults | server.tls.cert_file, server.tls.key_file |
| vc (HTTP) | Per-service opt-in | Go stdlib defaults | api_server.tls.{enable,cert_file_path,key_file_path} |
| vc (gRPC) | TLS 1.2 | Go stdlib defaults | Full mTLS with client CA, cert fingerprint pinning |
All server-side TLS uses Go's crypto/tls library with its default cipher suite selection, which excludes weak ciphers and prefers AEAD suites.
Client-Side TLS (Outbound)
| Component | Min Version | SSRF Protection | mTLS |
|---|---|---|---|
| go-trust (SafeHTTPClient) | TLS 1.2 | Yes — private IP, cloud metadata, DNS rebinding | No |
| go-wallet-backend | Configurable | No | No |
| facetec-api → FaceTec | Configurable | No | Yes (optional) |
| facetec-api → vc apigw | TLS 1.2 | No | Yes (optional) |
| vc issuer ↔ registry (gRPC) | TLS 1.2 | N/A (internal) | Yes (cert pinning) |
go-trust hardened cipher suite
go-trust's SafeHTTPClient enforces an explicit cipher suite list for all trust resolution HTTP calls:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
Channel Authentication
HTTP API (go-wallet-backend, facetec-api)
All API requests (except health probes) are authenticated via JWT bearer tokens:
Authorization: Bearer <jwt>
- Algorithm: HMAC-SHA256 (HS256)
- Claims:
user_id,tenant_id,jti,exp,iss,aud - Validation: Middleware verifies signature, checks expiry, extracts tenant context
- Revocation: In-memory JTI blacklist with periodic cleanup
WebSocket (go-wallet-backend)
WebSocket connections are authenticated in the first message after upgrade:
- Client opens WebSocket connection over TLS on dedicated port (default 8082).
- Client sends JSON message containing
tokenfield. - Server validates JWT (same HMAC secret as HTTP API), extracts
user_id. - Connection promoted to authenticated; subsequent messages routed to user's keystore session.
Admin API (go-wallet-backend)
Admin endpoints on separate port (default 8081) use pre-shared bearer token with constant-time comparison (crypto/subtle.ConstantTimeCompare).
gRPC mTLS (vc)
Inter-service gRPC connections between issuer and registry support full mTLS:
- Server:
tls.RequireAndVerifyClientCertwhen client CA configured - Client identity verified by: SHA-256 cert fingerprint (
AllowedClientFingerprints) and/or Distinguished Name (AllowedClientDNs)
SSRF Protection
go-trust SafeHTTPClient
All HTTP requests for trust resolution (ETSI TSL, DID resolution, OpenID Federation) use SafeHTTPClient with:
| Protection | Mechanism |
|---|---|
| Private IP blocking | Blocks RFC 1918, loopback, link-local ranges |
| Cloud metadata blocking | Blocks 169.254.169.254 (AWS/GCP/Azure metadata) |
| DNS rebinding protection | Validates all resolved IPs before connecting |
| HTTPS enforcement | Requires HTTPS by default (AllowHTTP flag for dev/test only) |
| Host allowlisting | Optional allowlist of permitted hostnames |
| Redirect validation | Each redirect target checked against SSRF rules |
vc Config Validation
The vc platform applies safe_uri validation tags on configuration URL fields, which at config load time:
- Performs DNS resolution on configured URLs
- Blocks private IP ranges, loopback, link-local, localhost
- Rejects configurations pointing to internal services
go-wallet-backend
The go-wallet-backend HTTPClientConfig does not include SSRF protection. Outbound calls are limited to configured upstream URLs (vc apigw, OIDC providers) set at deployment time by the operator.
Storage Protection
Client-Side (Wallet Frontend)
All sensitive wallet data is protected through the key hierarchy:
| Data | Protection | Storage Location |
|---|---|---|
| Credential signing keys | AES-256-GCM within JWE container | Backend (encrypted blob) |
| Wallet state | AES-256-GCM within JWE container | Backend (encrypted blob) |
| Session token | Plaintext | Browser sessionStorage (tab-scoped) |
| Cached user data | As received from server | Browser IndexedDB (offline access) |
The backend stores only the opaque encrypted privateData blob — it cannot decrypt wallet contents.
Server-Side
| Data | Protection | Storage |
|---|---|---|
| User records | Application-level access control (tenant isolation) | MongoDB |
| Credential records | Tenant-scoped, holder DID-indexed | MongoDB |
| MongoDB connection | Optional mTLS (cert_path, key_path, ca_path) | N/A |
| Configuration secrets | Filesystem permissions, env vars, or file paths | Operator responsibility |
Security Headers
facetec-api sends security headers on all responses:
| Header | Value |
|---|---|
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Cache-Control | no-store |
wallet-frontend security headers are enforced by startup-time nginx configuration (see nginx-security-headers-config.sh).\ngo-wallet-backend and go-trust currently rely on CORS controls but do not yet set dedicated API security headers middleware; tracks adding X-Content-Type-Options: nosniff and Cache-Control: no-store to both services.\n