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

# Security

> Protect Flowker workflows, data, and integrations with Access Manager authentication, per-connection credentials, and deployment-managed TLS.

export const GDSL = ({children}) => <Tooltip headline="DSL (Domain-Specific Language)" tip="A simplified language designed for a specific purpose — in Flowker's case, for defining workflow steps and rules without writing general-purpose code." cta="See glossary" href="/en/glossary">
    {children}
  </Tooltip>;

Flowker protects your workflows, data, and integrations through Access Manager authentication and per-connection credential management. TLS for API traffic is managed by your deployment. This page covers the security model as implemented in the current release.

## Platform authentication

***

Flowker delegates platform authentication to **Access Manager**, enabled with `PLUGIN_AUTH_ENABLED`. When enabled, every request to a protected API route must carry a Bearer token (OIDC JWT), and each protected route enforces a per-resource, per-action permission — this is how role- and policy-based authorization is applied.

Enable Access Manager in production.

```bash theme={null}
curl -X GET https://your-flowker-instance/v1/workflows \
  -H "Authorization: Bearer <token>"
```

**How it works:**

* **Access Manager enabled** — each request to a protected API route carries a Bearer token, and every protected route enforces a per-resource, per-action permission.
* **Access Manager disabled** — endpoints do not require authentication. The identity from a Bearer token, when present, is still read on a best-effort basis, so the request is attributed to the claimed subject. Use this mode only for local development.
* Invalid or missing credentials return `401 Unauthorized`.

**Health probe exception:**

Liveness and readiness probes are excluded from authentication. They are designed for infrastructure monitoring (Kubernetes probes, load balancers) and do not expose sensitive data.

## Provider authentication

***

When Flowker calls an external service, it authenticates with the credentials on the provider configuration that the node calls through. Your platform credentials and your provider credentials are managed separately.

**Supported authentication types:**

| Type                      | Description                                                               | Use case                                                |
| ------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------- |
| `none`                    | No authentication                                                         | Internal services behind a VPN or service mesh          |
| `api_key`                 | API Key sent as header or query parameter                                 | Third-party APIs with key-based access                  |
| `bearer`                  | Bearer token in the `Authorization` header                                | Services using static or pre-generated tokens           |
| `basic`                   | HTTP Basic authentication (username:password)                             | Legacy systems or internal APIs                         |
| `oidc_client_credentials` | OAuth 2.0 client credentials flow                                         | Machine-to-machine integrations with identity providers |
| `oidc_user`               | OAuth 2.0 user token flow                                                 | Integrations that act on behalf of a specific user      |
| `oauth2_token_endpoint`   | OAuth 2.0 client credentials against a token endpoint (no OIDC discovery) | OAuth2-style providers without OIDC discovery metadata  |
| `hmac`                    | Request signing with a shared HMAC secret                                 | Providers that verify a request signature header        |

The `config.auth` block on the provider configuration holds the authentication the external service requires, as a `{ type, config }` pair. Flowker applies it to every call a node makes through that connection.

Secret leaves in `config.auth` — an API key, bearer token, password, client secret, or HMAC secret — are sent to the secrets backend and removed from the persisted configuration. When secret read-back is configured, an authorized provider-configuration read can resolve them for display. Restrict that permission and treat its response as sensitive.

Anything else you place in the configuration document — a header, for example — is stored with the configuration, and a read can return it. Put each credential in `config.auth`.

To rotate a secret, send the new value in an update. To keep the current one, omit the field or send it blank — this works while `auth.type` stays the same. An update that changes `auth.type` must carry a value for each secret the new type requires and the previous one did not, otherwise Flowker rejects it with `FLK-0952`. A change between two types that use the same secret, such as `oidc_user` to `oidc_client_credentials`, does not need that value again.

```json theme={null}
{
  "config": {
    "auth": {
      "type": "bearer",
      "config": {
        "token": "eyJhbGciOiJSUzI1NiIs..."
      }
    }
  }
}
```

<Note>
  For OIDC flows (`oidc_client_credentials` and `oidc_user`), Flowker handles token acquisition and refresh automatically. For `oidc_client_credentials`, provide the issuer URL, client ID, and client secret. For `oidc_user`, provide the issuer URL, client ID, username, and password; `client_secret` is optional for public clients.
</Note>

## Network security

***

**TLS:**

* Configure TLS termination for Flowker API traffic in your deployment.
* Use `https://` base URLs for external calls. Flowker accepts a URI for the generic HTTP provider's `base_url`; it does not restrict it to HTTPS.
* Transmit credentials and sensitive payloads only over encrypted links.

**CORS configuration:**

Flowker supports configurable CORS settings:

* Allowed origins are configurable per deployment
* Credentials are not allowed in cross-origin requests (`AllowCredentials` is disabled)
* Preflight responses are cached for performance

## Resilience

***

Flowker protects against cascading failures from external services using circuit breaker and retry patterns.

**Circuit breaker:**

When an external service fails repeatedly, the circuit breaker opens and stops sending requests — preventing your workflows from hanging on an unresponsive provider.

* Transitions through `closed` → `open` → `half-open` states
* The circuit is scoped per provider configuration and per tenant, so failures against one connection do not affect another
* Thresholds are configured globally (consecutive failures before opening)
* The half-open state allows a limited number of test requests before fully closing

**Retries:**

Flowker resolves the retry budget for each node with the first two rules. The failure class then decides whether that budget is spent:

1. **Node opt-in.** A `retry.max_attempts` greater than `1` turns retries on whatever the method is. The value is the total attempt count, and the platform caps it at 5. A `retry.max_attempts` of `1` is not an opt-in — it sets a single attempt.
2. **HTTP method.** With no opt-in, `POST` and `PATCH` are treated as non-idempotent and get a single attempt. `GET`, `HEAD`, `OPTIONS`, `PUT`, `DELETE`, and any other verb retry, with 3 total attempts by default.
3. **Failure class.** The budget is spent only on a transient failure: a network error, a timeout on the attempt, any `5xx` status, or status `408` or `429`. Every other `4xx` fails on the first attempt however high the budget is. An open circuit, a cancelled execution, a request body over the configured size cap, and a response body over the same cap also stop the loop.

Backoff is exponential with full jitter. Each wait is a random value between zero and a ceiling. The ceiling starts at 1 second and doubles on each attempt. `retry.backoff_seconds` sets the first ceiling, between 1 and 60. The random wait prevents many executions from retrying the same service at the same moment.

## What's next

***

<CardGroup cols={2}>
  <Card title="Integration guide" icon="plug" href="/en/flowker/integration-guide">
    Learn how to create provider configurations and connect external services.
  </Card>

  <Card title="Observability" icon="chart-line" href="/en/flowker/flowker-observability-guide">
    Monitor Flowker with traces, metrics, and structured logs.
  </Card>
</CardGroup>
