> ## Documentation Index
> Fetch the complete documentation index at: https://docs.strait.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> 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.

<Info>
  Related guides: [Authentication & Authorization](/guides/authentication), [OIDC Authentication](/guides/oidc), [RBAC & Policy Authorization](/guides/rbac), [Audit Events](/guides/audit-events), [API Key Rotation](/guides/api-key-rotation).
</Info>

## 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](/guides/authentication) 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](/guides/authentication#role-based-access-control-rbac) 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).

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