Zero Trust Security & Observability
Shyntr is built with a security-first mindset, adhering to strict industry standards. Every component is designed under Zero Trust principles—never trust, always verify.
Security Standards Compliance
Token Architecture & Rotation
Shyntr implements a hybrid, high-assurance token model designed specifically for Zero Trust architectures:
- JWT Access Tokens (RFC 9068): Access tokens are issued as stateless JSON Web Tokens. Downstream resource servers can verify identity, permissions (
scp), tenant isolation (tenant_id), and authentication methods (amr) cryptographically without querying the database. - Opaque Refresh Tokens: To guarantee immediate revocation capabilities and prevent replay attacks, refresh tokens are strictly stateful (opaque). They are never issued as JWTs.
- Refresh Token Rotation & Grace Period: Every time a refresh token is used, a new token family is generated. To prevent race conditions and network latency issues, Shyntr enforces a strict 15-second grace period. During this window, the old token is marked inactive but is temporarily accepted, completely neutralizing token cloning attempts.
OpenID Connect Core 1.0
Shyntr implements full OpenID Connect compliance:
| Feature | Support |
|---|---|
prompt parameter | none, login, consent, select_account |
max_age parameter | Session age validation |
auth_time claim | Authentication timestamp in ID Token |
acr / amr claims | Authentication context and methods |
| Scope validation | Strict validation against client configuration |
| Nonce validation | Replay protection for implicit flows |
# Using max_age=0 forces re-authentication
GET /authorize?
client_id=app123&
response_type=code&
scope=openid%20profile&
max_age=0&
prompt=login
RP-Initiated Logout
Secure session termination following OpenID Connect RP-Initiated Logout 1.0:
GET /oauth2/logout?
id_token_hint=eyJhbGciOiJSUzI1NiIs...&
post_logout_redirect_uri=https://app.example.com/logged-out&
state=xyz123
| Validation | Description |
|---|---|
id_token_hint | Required for identifying the session to terminate |
post_logout_redirect_uri | Validated against pre-registered URIs |
| Session invalidation | All tokens for the session are revoked |
Advanced Security Features
RFC 7523: Private Key JWT Authentication
For high-security clients, Shyntr supports client authentication using signed JWTs instead of client secrets:
curl -X POST "https://auth.example.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=auth_code_here" \
-d "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
-d "client_assertion=eyJhbGciOiJSUzI1NiIs..."
The client assertion JWT must contain:
{
"iss": "client_id",
"sub": "client_id",
"aud": "https://auth.example.com/oauth2/token",
"jti": "unique-jwt-id",
"exp": 1234567890,
"iat": 1234567800
}
Use private_key_jwt authentication for:
- Machine-to-machine (M2M) applications
- Backend services
- Scenarios where client secrets cannot be stored securely
- Compliance requirements mandating asymmetric authentication
Replay Protection
Shyntr implements comprehensive replay protection across all protocols:
JWT ID (JTI) Tracking
Every JWT processed by Shyntr is checked against a replay cache:
┌─────────────────────────────────────────────────────────────┐
│ JTI Replay Protection │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. Client sends JWT with jti="abc123" │
│ 2. Shyntr checks: Is "abc123" in used_jti_cache? │
│ └─ If yes: Reject request (replay detected) │
│ └─ If no: Process request, add "abc123" to cache │
│ 3. Cache entry expires after JWT expiration + grace period │
│ │
└─────────────────────────────────────────────────────────────┘
SAML Message ID Tracking
SAML assertions are protected similarly:
InResponseTo: "_abc123def456"
└─ Tracked and validated against pending AuthnRequests
└─ Prevents assertion injection attacks
Tenant Isolation
Strict validation prevents cross-tenant data leakage:
func validateRequest(ctx context.Context, req *Request) error {
// Extract tenant from request context
tenantID := extractTenantID(req)
// Validate resource belongs to tenant
if resource.TenantID != tenantID {
// Log security event
audit.Log(ctx, AuditEvent{
Type: "cross_tenant_access_attempt",
TenantID: tenantID,
Resource: resource.ID,
Severity: "HIGH",
})
return ErrAccessDenied
}
return nil
}
Every API call, token validation, and resource access is checked against tenant boundaries. Attempting to use credentials from one tenant in another is logged as a security event and denied.
Refresh Token Rotation with Grace Period
Shyntr implements refresh token rotation with network-failure tolerance:
┌─────────────────────────────────────────────────────────────────┐
│ Refresh Token Rotation Flow │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. Client sends refresh_token_v1 │
│ 2. Shyntr issues new access_token + refresh_token_v2 │
│ 3. refresh_token_v1 enters grace period (not immediately │
│ invalidated) │
│ │
│ Grace Period Scenarios: │
│ │
│ ✅ Normal: Client uses refresh_token_v2 → Success │
│ ✅ Network failure: Client retries with refresh_token_v1 │
│ → Success (within grace period) │
│ ❌ Attack: Attacker uses refresh_token_v1 after v2 was used │
│ → Fail (entire refresh token family revoked) │
│ │
└─────────────────────────────────────────────────────────────────┘
Enterprise Observability
W3C Trace Context (OpenTelemetry)
Shyntr natively integrates with OpenTelemetry for distributed tracing:
# Environment configuration
OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317
OTEL_SERVICE_NAME=shyntr
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
Every request includes trace context:
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
tracestate: shyntr=tenant:acme;flow:authorization
This enables:
- End-to-end request tracing across microservices
- Performance bottleneck identification
- Error correlation across distributed systems
- Compliance audit trails
Structured Logging
Production logging uses JSON format for machine parsing:
{
"level": "info",
"ts": "2024-01-15T10:30:45.123Z",
"caller": "oauth2/authorize.go:145",
"msg": "authorization_code_issued",
"trace_id": "0af7651916cd43dd8448eb211c80319c",
"span_id": "b7ad6b7169203331",
"tenant_id": "acme",
"client_id": "dashboard-app",
"subject": "user_12345",
"scopes": ["openid", "profile", "email"],
"response_type": "code",
"duration_ms": 45
}
RFC 9457: Problem Details for HTTP APIs
All error responses follow the standard Problem Details format:
{
"type": "https://docs.shyntr.dev/errors/invalid_grant",
"title": "Invalid Grant",
"status": 400,
"detail": "The refresh token has expired or been revoked.",
"instance": "/oauth2/token",
"trace_id": "0af7651916cd43dd8448eb211c80319c"
}
Benefits:
- Predictable error structure across all endpoints
- Machine-readable error types
- Correlation with distributed traces
- Secure—no internal details leaked
Security Checklist for Production
Before deploying Shyntr to production, ensure:
-
APP_SECRETis a cryptographically random 32-byte string -
COOKIE_SECURE=trueis set (requires HTTPS) -
SKIP_TLS_VERIFY=falseis set (never true in production) -
GO_ENV=productionfor JSON logging -
GIN_MODE=releasefor performance optimization - Database connection uses SSL/TLS
- Admin API is not publicly accessible
- OpenTelemetry is configured for audit trails
- Rate limiting is configured at the network layer
Strict OIDC Configurations
To enforce Zero Trust principles, Shyntr does not grant all OAuth2/OIDC capabilities by default. Each Service Provider (Client) must be explicitly configured with the exact permissions it requires:
- Allowed Grant Types: Clients must explicitly request
authorization_code,refresh_token, orclient_credentials. If a frontend SPA tries to use a refresh token without this explicit grant, Shyntr will immediately reject the request. - Response Modes: Administrators can restrict how tokens are returned to the client (
query,fragment, orform_post), preventing token leakage in URL logs.
RP-Initiated Logout (Secure Sign-Out)
Handling logouts in a federated environment is just as critical as logins. Shyntr implements the OIDC RP-Initiated Logout specification to ensure users are safely signed out from the Identity Hub and their sessions are terminated securely.
To prevent Open Redirect Attacks, Shyntr strictly validates the post_logout_redirect_uri. If the requested return URL is not whitelisted in the Client's configuration, the logout redirect is aborted.
Headless Logout Flow
By keeping the Auth Portal (Next.js) fully decoupled from the Backend, Shyntr ensures that all user-facing consent and logout screens can be customized per tenant while the cryptographic validation remains securely locked in the Go backend.
Cryptographic Standards
| Algorithm | Usage | Specification |
|---|---|---|
| AES-256-GCM | Secret encryption at rest | NIST SP 800-38D |
| RSA-2048+ | JWT signing, SAML signatures | RFC 7518 |
| SHA-256 | Token hashing, integrity | FIPS 180-4 |
| ECDSA P-256 | Alternative JWT signing | RFC 7518 |
| PBKDF2 | Key derivation (if needed) | RFC 2898 |
Content Security Policy (CSP) & Auto-Submit Forms
In SAML 2.0 HTTP-POST bindings, Identity Providers must automatically POST an HTML form containing the signed XML response to the Service Provider. This requires an inline JavaScript execution (onload="document.forms[0].submit()").
By default, Shyntr's global security middleware heavily restricts inline scripts to prevent Cross-Site Scripting (XSS). However, Shyntr intelligently overrides the Content-Security-Policy header strictly and only on the exact SAML Response rendering endpoints:
// Safely applied only to the SAML auto-submit response writer
c.Writer.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';")
Advanced Replay Protection (Stateful SAML)
Standard SAML libraries block the processing of the same XML ID twice to prevent Replay Attacks. However, in a headless architecture, the login flow is split into two phases (pre-login and post-login), which traditionally causes false-positive replay alerts.
Shyntr solves this by parsing the SAMLRequest only once at the perimeter. The validated AssertionConsumerServiceURL and Issuer are securely cached in the database's isolated Context storage. When the user returns from the headless login UI, Shyntr reconstructs the SAML session entirely from the trusted backend database, bypassing the need to re-parse the external XML and completely neutralizing replay vulnerabilities.
Outbound Network Security
Zero Trust in Shyntr is not limited to identity and token validation.
It also applies to outbound network communication.
Why It Matters
Outbound HTTP requests can introduce critical risks:
- Server-side request forgery (SSRF)
- Internal network exposure
- Access to cloud metadata services
- Data exfiltration
Enforcement Model
All outbound requests are validated before execution.
Validation includes:
- URL structure checks
- DNS resolution constraints
- IP classification (private, loopback, etc.)
- Policy evaluation
Default Protections
By default, Shyntr blocks:
- Private IP ranges
- Loopback addresses
- Link-local addresses
- Multicast addresses
- Localhost references
Policy-Driven Behavior
Outbound behavior is governed by:
- Tenant-level policies
- Global fallback policy
Shyntr initializes secure global outbound policies during migration, ensuring that outbound controls are active even before tenant-specific customization is added.
If no policy explicitly allows the request:
Request → DENIED
TLS Handling
TLS verification is enforced by default.
The SKIP_TLS_VERIFY option exists only for development and does not bypass policy enforcement.
Shyntr treats outbound network access as a privileged operation, not a default capability.
For the full outbound security model—including tenant/global policy resolution, enforcement points, and request evaluation rules—see Outbound Policy & Network Boundaries.
Next Steps
- Deploy with Docker Compose
- Configure Environment Variables
- Set up Headless Login & Consent