Strait Docs
Guides

Security features and protections implemented in Strait.

Strait includes several built-in security measures to protect the infrastructure and ensure the integrity of job executions.

SSRF Protection

To prevent Server-Side Request Forgery (SSRF), all user-provided URLs (e.g., for webhooks or job endpoints) are validated using the validateURL function.

Blocked Hosts

The following hosts are explicitly blocked:

  • localhost
  • metadata.google.internal
  • 169.254.169.254 (Cloud metadata service)

Private IP Detection

The system performs DNS resolution and checks if any of the resolved IP addresses belong to blocked ranges. This prevents access to internal network services.

Blocked IP Ranges

  • Private IPv4: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
  • Loopback: 127.0.0.0/8, ::1/128
  • Link-local: 169.254.0.0/16
  • CGNAT: 100.64.0.0/10
  • IPv6 Unique Local: fc00::/7

Defense in Depth

SSRF validation is applied in two layers:

  1. API layer: On job create/update for endpoint_url, fallback_endpoint_url, and webhook_url
  2. Worker layer: At dispatch time for environment-resolved endpoint overrides (apps/strait/internal/worker/validate.go)

Allowed Ports

To further restrict outbound traffic, only a specific set of standard and common development ports are allowed for webhooks:

  • 80, 443 (Standard HTTP/S)
  • 3000, 4000, 5000 (Common web frameworks)
  • 8080, 8443 (Alternative HTTP/S)
  • 9000 (Common API port)

Rate Limiting

Strait implements rate limiting at multiple levels using the httprate middleware.

Global Rate Limit

Controlled by the RATE_LIMIT_REQUESTS environment variable. This limits the total number of requests a single IP can make within the RATE_LIMIT_WINDOW.

Per-Trigger Rate Limit

Controlled by TRIGGER_RATE_LIMIT_REQUESTS. This specifically limits the /trigger endpoints to prevent accidental or malicious job flooding.

RBAC Control-Plane Rate Limits

Mutating RBAC endpoints (role/member/tag-policy/resource-policy management and seed-role operations) have stricter per-route limits to reduce abuse risk on authorization control paths.

Request Protections

Timeouts

The REQUEST_TIMEOUT middleware ensures that no API request hangs indefinitely. The default timeout is 30 seconds if not specified.

Body Size Limits

The maximum allowed request body size is capped to prevent Denial of Service (DoS) attacks via large payloads.

  • Default: 1MB (MAX_REQUEST_BODY_SIZE)

Validation

All incoming JSON requests are validated using the go-playground/validator library. This ensures that required fields are present and data formats (like UUIDs or email addresses) are correct before processing.

CORS Configuration

Cross-Origin Resource Sharing (CORS) is configured to allow secure access from web dashboards.

  • Allowed Origins: Configurable via CORS_ALLOWED_ORIGINS.
  • Allowed Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS.
  • Allowed Headers: Includes Authorization, X-Internal-Secret, and idempotency keys.

Input Sanitization

The system uses a strict approach to input:

  • Disallow Unknown Fields: The JSON decoder is configured to fail if unknown fields are present in the request body.
  • Type Safety: Strong typing in Go ensures that input data matches the expected domain models.
  • Constant-Time Comparison: Used for internal secret validation to prevent timing attacks.

API Key Scope Enforcement

Every API key has a set of scopes that restrict what it can do. Scopes are checked on every request by the requirePermission middleware. See Authentication & Authorization for the full scope list.

Keys with empty scopes ([]) retain full access for backwards compatibility.

Role-Based Access Control

Users accessing Strait through the app are authorized via project roles. Each role defines a set of permissions identical to API key scopes. Four system roles (admin, operator, viewer, triggerer) are available, and custom roles can be created per-project.

RBAC also supports role inheritance and policy-based grants (resource policies and tag policies) for finer-grained authorization without over-broad static roles.

See Authentication & Authorization for details.

Actor Identity & Audit Trail

Every mutation records which actor performed it:

  • API key requests: actor is apikey:<key-id>
  • User requests: actor is the X-Actor-Id header value (set by the app)

These are stored as created_by and updated_by columns on jobs, workflows, and runs.

Impersonation Protection

API key requests never honor X-Actor-Id headers. This prevents an API key holder from setting X-Actor-Id: admin_user to gain that user's RBAC permissions. Actor headers are only trusted on internal secret authentication (service-to-service).

Security is a shared responsibility. While Strait provides these protections, ensure your job endpoints also implement proper authentication and input validation.

Was this page helpful?

On this page