Skip to main content
Version: 1.13.x (Next)

Catalog and model policy

On a shared Langflow server, anyone who can build a flow can use every component and model.

Superusers can create catalog and model policy to hide components, templates, model providers, and models from the Langflow visual builder.

OSS Langflow has no visual editor for policy management. Instead, use the APIs on this page with a superuser API key or session. This is the same credential the Users API requires.

An empty policy is the default, and has no restrictions. Nothing is restricted until a superuser writes a policy.

The four lists of restrictions are saved in one policy bundle. Replace the policy bundle with a PUT request. Send every list you want in effect with the PUT request. Send [] for a list you want unrestricted.

You want to…FieldExample
Hide a component and refuse flows that use itblocked_​component_​keysPythonREPLComponent (Python Interpreter)
Hide a starter templateblocked_​template_​keysbasic_​prompting
Allow only some providersapproved_​provider_​ids["openai", "anthropic"]. [] means every provider.
Block a modelblocked_​model_​keysgpt-4o, openai::gpt-4o, or openai::llm::gpt-4o

A blocked component disappears from the palette. Saving or running a flow that still contains the component fails.

A blocked template is omitted from the starter list.

tip

Catalog policy hides or refuses named components, including built-ins.

To block creating and editing custom code, set LANGFLOW_ALLOW_CUSTOM_COMPONENTS. To block built-in code-execution components at runtime without a policy bundle, set LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS.

Apply a policy

tip

Apply any database migrations before sending requests to these endpoints. An uninitialized bundle returns 503.

  1. Create a superuser API key.

  2. Query how many flows a component would affect before you block it.

    GET /api/v1/catalog-policy/usage returns the number of affected flows. GET /api/v1/catalog-policy/usage/flows?component=PythonREPLComponent lists the affected flows.

    For field names and key formats, see How to name what you block.

  3. Read the current policy bundle, and copy revision.

    import os

    import requests

    url = f"{os.environ['LANGFLOW_URL']}/api/v1/policy-bundle"
    headers = {
    "accept": "application/json",
    "x-api-key": os.environ["LANGFLOW_API_KEY"],
    }

    response = requests.get(url, headers=headers)
    response.raise_for_status()
    print(response.json())
    Result
    {
    "revision": 1,
    "initialized": true,
    "source": "default",
    "approved_provider_ids": [],
    "blocked_component_keys": [],
    "blocked_template_keys": [],
    "blocked_model_keys": [],
    "content_hash": "ef74cccb21593ac02fc514e669c911768e740b1135d7a91d3fb15f72837ab762",
    "created_at": null,
    "created_by": null,
    "reason": null,
    "rollback_of_revision": null,
    "managed_externally": false
    }
    tip

    If managed_externally is true, an external controller owns policy. Reads still work. Writes return 409.

  4. Replace the bundle with a PUT request that includes every list you want in effect. Send the revision number copied from step 3 as expected_revision. Send [] for a list you want unrestricted.

    import os

    import requests

    base = os.environ["LANGFLOW_URL"]
    headers = {
    "accept": "application/json",
    "Content-Type": "application/json",
    "x-api-key": os.environ["LANGFLOW_API_KEY"],
    }

    current = requests.get(f"{base}/api/v1/policy-bundle", headers=headers)
    current.raise_for_status()
    revision = current.json()["revision"]

    payload = {
    "expected_revision": revision,
    "approved_provider_ids": ["openai", "anthropic"],
    "blocked_component_keys": ["PythonREPLComponent"],
    "blocked_template_keys": [],
    "blocked_model_keys": ["openai::llm::gpt-4o"],
    "reason": "Limit providers and block code execution",
    }

    response = requests.put(f"{base}/api/v1/policy-bundle", headers=headers, json=payload)
    response.raise_for_status()
    print(response.json())

    If another user updated the policy first, the PUT returns 409. Repeat from step 3 with an updated revision number.

    {
    "detail": {
    "message": "Policy bundle revision conflict",
    "expected_revision": 1,
    "active_revision": 2
    }
    }
  5. Optional: Undo a prior revision.

    GET /api/v1/policy-bundle/history lists prior bundle policy revisions.

    To restore a revision, POST to /api/v1/policy-bundle/rollback/{revision} with the current expected_revision:

    curl -X POST \
    "$LANGFLOW_URL/api/v1/policy-bundle/rollback/1" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -H "x-api-key: $LANGFLOW_API_KEY" \
    -d '{"expected_revision": 2, "reason": "Revert last change"}'

How to name blocked items

Components use the type stored in the flow JSON, such as PythonREPLComponent or ChatInput. That is the component's class identity, not the label in the visual builder. Keys are case-sensitive. Older aliases still match, so blocking PythonREPLComponent also catches nodes saved under a previous type for the same component.

"blocked_component_keys": ["PythonREPLComponent"]

Starter templates use a lowercase slug of the English name with underscores, such as basic_prompting.

"blocked_template_keys": ["basic_prompting"]

Providers use lowercase IDs, such as openai. GET /api/v1/model-provider-policy lists every provider the process is aware of, with provider_id and display name.

"approved_provider_ids": ["openai", "anthropic"]

Models use the identities in the model picker.

"blocked_model_keys": ["gpt-4o", "openai::gpt-4o", "openai::llm::gpt-4o"]

Change one list at a time

Use these endpoints when you want to change only components, templates, or providers. If you are changing more than one list, use one PUT to /api/v1/policy-bundle instead. See Apply a policy.

  1. To hide or unhide components, PUT the complete blocked list to /api/v1/catalog-policy/components. A PUT replaces the whole list. Send {"blocked": []} to unblock every component.

    curl -X PUT \
    "$LANGFLOW_URL/api/v1/catalog-policy/components" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -H "x-api-key: $LANGFLOW_API_KEY" \
    -d '{"blocked": ["PythonREPLComponent"]}'

    To read the current list first, GET /api/v1/catalog-policy/components.

  2. To hide or unhide starter templates, PUT the complete blocked list to /api/v1/catalog-policy/templates.

    curl -X PUT \
    "$LANGFLOW_URL/api/v1/catalog-policy/templates" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -H "x-api-key: $LANGFLOW_API_KEY" \
    -d '{"blocked": ["basic_prompting"]}'

    To read the current list first, GET /api/v1/catalog-policy/templates.

  3. Optional: List the flows that include a component.

    GET /api/v1/catalog-policy/usage returns the number of flows. GET /api/v1/catalog-policy/usage/flows?component=PythonREPLComponent lists the affected flows.

  4. To allow only some providers, PUT the complete approved list to /api/v1/model-provider-policy. Send {"approved_provider_ids": []} to allow every provider.

    curl -X PUT \
    "$LANGFLOW_URL/api/v1/model-provider-policy" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -H "x-api-key: $LANGFLOW_API_KEY" \
    -d '{"approved_provider_ids": ["openai", "anthropic"]}'

    Set blocked_model_keys with PUT /api/v1/policy-bundle.

See also

Was this page helpful?

Support
Search