Back to Langflow

Authorization

docs/docs/Develop/authorization.mdx

1.12.0.dev2511.2 KB
Original Source

Langflow includes a pluggable authorization layer for role-based access control (RBAC) over flows, projects, deployments, files, variables, and knowledge bases.

The authorization infrastructure is present in all Langflow deployments, but the open-source build registers a pass-through service that always allows every action for every authenticated user.

Setting LANGFLOW_AUTHZ_ENABLED=true without an enforcement plugin does not restrict access. Route guards still run and audit rows can still be written, but no policy is applied.

Per-resource RBAC enforcement requires a registered authorization plugin. Langflow OSS does not include a registered authorization plugin.

Enable RBAC with an enforcement plugin

The following steps apply when you have a registered enforcement plugin.

  1. Set LANGFLOW_AUTHZ_AUDIT_ENABLED=true and run Langflow in a staging environment. Review the audit log to understand what decisions would be made before enforcement is on.

  2. Install and register the enforcement plugin following its setup guide.

  3. Set LANGFLOW_AUTHZ_ENABLED=true. The plugin reads the role and share tables and applies its policy.

  4. Use the roles API and role assignments API to assign the built-in viewer, developer, or admin roles to your users, or create custom roles.

  5. Use the shares API to grant cross-user access where needed.

Configure authorization environment variables

VariableDescriptionDefault
LANGFLOW_AUTHZ_ENABLEDEnable authorization enforcement. Requires a registered enforcement plugin. When false, all requests pass regardless of roles or shares.false
LANGFLOW_AUTHZ_SUPERUSER_BYPASSWhen true, active superusers bypass authorization checks. The plugin may still audit the decision.true
LANGFLOW_AUTHZ_AUDIT_ENABLEDWrite an audit log row for every authorization decision and share-administration action. Works independently of LANGFLOW_AUTHZ_ENABLED — set this to true while enforcement is off to observe traffic before enabling enforcement.false
LANGFLOW_AUTHZ_AUDIT_DURABLEWait for each accepted audit row to commit. A full bounded queue applies backpressure and persistence failures fail the triggering request with a sanitized error. Enable this before treating the audit table as a compliance or external-delivery source.false
LANGFLOW_AUTHZ_AUDIT_RETENTION_DAYSNumber of days to retain audit log rows. Set to 0 to disable automatic pruning.90
LANGFLOW_AUTHZ_AUDIT_CLEANUP_INTERVALSeconds between retention sweep runs. A sweep also runs on startup. Minimum 300.86400

The default audit producer is intentionally best effort to preserve the OSS request-path behavior: a saturated queue or exhausted database flush can lose a row. Durable mode is explicit and fail-closed. It assigns the event ID and event time before enqueue, applies bounded backpressure, and acknowledges the caller only after the batch commits. Producer health reports only counters and bounded failure class names; database exception text is never exposed.

System roles

Langflow seeds three built-in system roles that an enforcement plugin uses as a starting point for policy sync. These roles cannot be deleted.

RolePermission slugs
viewerflow:read, project:read, deployment:read, file:read, variable:read, knowledge_base:read
developerviewer permissions plus flow:write, flow:execute, file:write, variable:write
adminAll actions on all resource types

You can create additional roles with the roles API. Role assignments take effect only after an enforcement plugin is registered.

Authorization API reference

All authorization endpoints are under /api/v1/authz/. Write operations require superuser privileges.

These endpoints manage the RBAC data model. An enforcement plugin consumes roles, assignments, and shares when evaluating requests. Without a plugin, API responses succeed but access is not restricted.

Shared-flow execution identity

A share delegates an action on a resource; it does not delegate the owner's identity or credentials.

For an authenticated shared-flow run, the authenticated caller is the execution principal. Variables, files, nested flows, messages, jobs, and other dependencies resolve in that caller's namespace. A dependency must therefore be owned by the caller or shared with the caller separately. Langflow never falls back to the flow owner's credentials when a caller-owned or explicitly shared dependency is unavailable.

Only the flow owner can submit graph data or component-parameter tweaks. A non-owner receives the same not-found response as a caller without access so the rejection does not confirm that the flow exists.

Revoking a share prevents new runs and rechecked continuations, including HITL resume. It does not change the principal of work that is already running or terminate that work. Deployments and legacy public entry points are explicit exceptions:

  • Public V1/V2 and unauthenticated A2A (auth_type=none) entry points execute with a stable, non-persisted anonymous principal under visitor-isolated session and storage namespaces. They never inherit the published flow owner's credentials, variables, files, or Memory Bases, and public requests cannot submit graph data or tweaks. Protected A2A (apikey or oauth) continues to require and execute as the flow owner.
  • Deployment authorization and audit use the requesting actor, while the external deployment data plane continues to use the deployment owner's provider namespace. Provider controls govern already-running work.
  • Webhooks, legacy MCP, and project MCP remain owner-scoped admission surfaces in this release; they do not widen execution to shared flows. Webhook request data is the one trusted server-generated tweak and is mapped only to the published Webhook Component.

Owner-only execution retains detailed component errors for debugging. Delegated and public execution returns a stable generic workflow error without a component traceback or provider detail. Server logs and telemetry keep the original exception.

:::important Upgrade note: paused public A2A tasks An A2A HITL resume requires the stored checkpoint's principal to match the principal the current request was admitted under. Checkpoints written before anonymous public execution existed recorded the flow owner, while an auth_type=none folder now admits the anonymous principal, so a public A2A task that is paused across this upgrade cannot be resumed and returns 404. There is no compatibility read for these rows on purpose: accepting an owner-principal checkpoint under an anonymous principal is exactly the protected-to-public transition this check exists to block. Drain or cancel paused public A2A tasks before upgrading, then start them again. Protected (apikey, oauth) A2A tasks are unaffected. :::

The machine-validated endpoint-family contract is maintained in scripts/ci/execution_principal_matrix.json. Changes to a listed runtime surface must update that matrix and its referenced tests.

Effective permissions

POST /api/v1/authz/me/permissions

Returns the allowed actions for a set of resources for the current user, without making individual resource requests that would trigger 403 responses. The frontend uses this to enable or disable UI controls when an enforcement plugin is active.

Request body:

FieldTypeDescription
resource_typestringOne of: flow, deployment, project, knowledge_base, variable, file, component
resource_idsUUID[]Resource IDs to evaluate. Maximum 500 per request.
actionsstring[]Actions to check. Defaults to read, write, execute, delete, create. Maximum 10.
domainstringAuthorization domain. Typically project:{folder_id} or *. Defaults to *.

Response:

json
{
  "resource_type": "flow",
  "permissions": {
    "3fa85f64-5717-4562-b3fc-2c963f66afa6": ["read", "execute"]
  }
}

Shares API

/api/v1/authz/shares

Shares grant access to a resource across user boundaries. The resource owner or a superuser can administer shares for their own resources.

MethodPathDescription
POST/api/v1/authz/sharesCreate a share
GET/api/v1/authz/sharesList shares visible to the current user
GET/api/v1/authz/shares/{share_id}Get a specific share
PATCH/api/v1/authz/shares/{share_id}Update a share
DELETE/api/v1/authz/shares/{share_id}Delete a share

Each share write fires an invalidation call to the authorization plugin so cached policy is refreshed.

Roles API

/api/v1/authz/roles — superuser only for writes

MethodPathDescription
GET/api/v1/authz/rolesList roles. Filter by is_system or name substring.
GET/api/v1/authz/roles/{role_id}Get a specific role
POST/api/v1/authz/rolesCreate a custom role
PATCH/api/v1/authz/roles/{role_id}Update a role name, description, or permissions
DELETE/api/v1/authz/roles/{role_id}Delete a custom role (system roles cannot be deleted)

Role assignments API

/api/v1/authz/role-assignments — superuser only for writes

MethodPathDescription
GET/api/v1/authz/role-assignmentsList role assignments
POST/api/v1/authz/role-assignmentsAssign a role to a user
DELETE/api/v1/authz/role-assignments/{assignment_id}Remove a role assignment

Teams API

/api/v1/authz/teams — superuser only for writes

MethodPathDescription
GET/api/v1/authz/teamsList teams
GET/api/v1/authz/teams/{team_id}Get a specific team
POST/api/v1/authz/teamsCreate a team
PATCH/api/v1/authz/teams/{team_id}Update a team
DELETE/api/v1/authz/teams/{team_id}Delete a team
GET/api/v1/authz/teams/{team_id}/membersList team members
POST/api/v1/authz/teams/{team_id}/membersAdd a member to a team
DELETE/api/v1/authz/teams/{team_id}/members/{user_id}Remove a member from a team

Audit log API

GET /api/v1/authz/audit — superuser only

Returns a paginated, filterable view of the authorization audit log.

Query parameters:

ParameterTypeDescription
user_idUUIDFilter by acting user
resource_typestringFilter by resource type slug (for example, flow)
resource_idUUIDFilter by resource UUID
actionstringFilter by action string (for example, flow:read or share:create)
resultstringFilter by decision: allow, deny, or owner_override
sincedatetimeInclusive lower bound on timestamp
untildatetimeExclusive upper bound on timestamp

Page size is capped at 200 rows.

See also