> ## 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/start-here/glossary">
    {children}
  </Tooltip>;

Flowker protects your workflows, data, and integrations through Access Manager authentication and per-connection credential management. Your deployment manages TLS for API traffic. 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 works.

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. When a Bearer token is present, Flowker still reads the identity from it on a best-effort basis. Flowker attributes the request 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 do not require authentication. They serve 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 stay separate.

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

Flowker sends secret leaves in `config.auth` (an API key, bearer token, password, client secret, or HMAC secret) to the secrets backend. Flowker then removes them from the persisted configuration. With secret read-back 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) stays 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
* Cross-origin requests cannot carry credentials (`AllowCredentials` stays off)
* Flowker caches preflight responses 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. This prevents your workflows from hanging on an unresponsive provider.

* Transitions through `closed` → `open` → `half-open` states
* Each circuit applies to one provider configuration and one tenant, so failures against one connection do not affect another
* You configure thresholds 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, Flowker treats `POST` and `PATCH` as non-idempotent and gives them a single attempt. Every other verb retries, with 3 total attempts by default. This includes `GET`, `HEAD`, `OPTIONS`, `PUT`, and `DELETE`.
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 and a cancelled execution also stop the loop. A request body over the configured size cap and a response body over the same cap stop it too.

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/products/flowker/integration-guide">
    Learn how to create provider configurations and connect external services.
  </Card>

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