---
title: "Core"
slug: "integration-core"
updated: 2026-05-18T12:15:16Z
published: 2026-05-18T12:15:16Z
---

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

# Core

*Early Access Capability*

          
  

This article provides a comprehensive overview of integrating and using the PlainID Authorization Platform Python package within your application. It covers essential setup steps, including installation and authentication, and explains core concepts such as identity context, permission retrieval, and Policy enforcement.

It also introduces advanced capabilities such as **category-based prompt filtering**, **anonymization of sensitive data**, and **SQL query authorization**.

## Installation

**Prerequisites**

- **Python 3.10–3.12**
- PlainID package

To install the PlainID package:

1. Run the following command:

```
pip install core-plainid
```

## Authentication

All components support three authentication modes. At least one must be available at request time.

| Mode | When to Use |
| --- | --- |
| Client credentials | Provide `client_id` and `client_secret` at construction time. |
| JWT token | Provide `client_id` and pass an `auth_token` per request via RequestContext. |
| IDP provider | Provide `client_id` and an IdpAuthProvider for automatic OAuth2 token management. |

Refer to our [API Client Credentials](/docs/environment-settings#api-client-credentials) documentation for more information about client credentials.

A per-request `auth_token` always takes precedence. If no `auth_token` is provided, the IDP provider is used to fetch a token. Only when neither is available does the client fall back to `client_secret`.

The `IdpAuthProvider` obtains and caches OAuth2 access tokens from an external Identity Provider. Tokens are fetched lazily in the background and automatically refreshed when they expire. When `idp_auth_provider` is set and no `auth_token` is provided per request, the provider automatically fetches a token from the IDP and uses it for authentication.

The following steps describe how to configure authentication using an IDP provider.

**To configure authentication using an IDP provider:**

1. Import the IdpAuthProvider:

```
from core_plainid.utils.idp_auth_provider import IdpAuthProvider
```
2. Initialize the provider with your Identity Provider details:

```
idp_provider = IdpAuthProvider(
    token_url="https://your-idp.com/oauth/token",
    client_id="your_idp_client_id",
    client_secret="your_idp_client_secret",
    audience="https://your-api-audience.com",
    resource="my-resource",
)
```
3. Pass the provider to the PlainIDPermissionsProvider:

```
permissions_provider = PlainIDPermissionsProvider(
    base_url="https://platform-product.us1.plainid.io",
    client_id="your_client_id",
    idp_auth_provider=idp_provider,
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `token_url` | `str` | Yes | The IDP token endpoint URL |
| `client_id` | `str` | Yes | OAuth2 client ID for the IDP |
| `client_secret` | `str` | Yes | OAuth2 client secret for the IDP |
| `grant_type` | `str` | No | OAuth2 grant type, default is `"client_credentials"` |
| `audience` | `str` | No | Audience parameter included in the token request |
| `**kwargs` |  | No | Additional fields included in the token request body |

## Identity Context

PlainID supports two identity resolution modes:

- **Explicit identity** via `entity_id`, `entity_type_id`, and optionally `additional_identities` in the request body.
- **Header-based identity** via the `headers` field, which forwards headers directly to the PlainID API. These headers are matched against configured values to resolve relevant entities. In this mode, `entity_id`, `entity_type_id`, and `additional_identities` are not required.

## Integration Flow

This section walks through initializing the client, defining identity, and retrieving permissions. The PlainIDPermissionsProvider is the main integration entry point.

**To integrate PlainID into your application:**

1. Initialize the PlainIDPermissionsProvider:

```
from core_plainid.utils.plainid_permissions_provider import PlainIDPermissionsProvider

permissions_provider = PlainIDPermissionsProvider(
    base_url="https://platform-product.us1.plainid.io",
    client_id="your_client_id",
    client_secret="your_client_secret",
)
```
2. Define the RequestContext representing the identity:

```
from core_plainid.models.context.request_context import RequestContext

request_context = RequestContext(
    entity_id="user_123",
    entity_type_id="user",
)
```
3. For agent-based or delegated execution flows, include additional identities (optional):

```
from core_plainid.models.context.request_context import (
    AdditionalIdentity,
    RequestContext,
)

request_context = RequestContext(
    entity_id="user_123",
    entity_id_type="user",
    additional_identities=[
        AdditionalIdentity(
            entity_id="agent_456",
            entity_type_id="agent",
        ),
    ],
)
```
4. Retrieve permissions from PlainID:

```
permissions = await permissions_provider.aget_permissions(request_context)

allowed_tools = permissions.tools
allowed_categories = permissions.categories
allowed_entities = permissions.entities
```

## Category Filtering

The Categorizer classifies prompts into categories and validates them against PlainID Policies. If the prompt categories are not permitted, a PlainIDCategorizerException is raised. Multiple identities are supported through RequestContext.

Before using this feature, configure a Ruleset in PlainID using the Prompt_Control template and define categories as Assets, for example contract, HR, and finance.

**To configure and use category filtering:**

1. Create a Ruleset in PlainID:

```
# METADATA
# custom:
# plainid:
# kind: Ruleset
# name: All
ruleset(asset, identity, requestParams, action) if {
    asset.template == "Prompt_Control"
}
```
2. Import the required classes:

```
from core_plainid.categorization.categorizer import Categorizer
from core_plainid.utils.plainid_permissions_provider import PlainIDPermissionsProvider
from core_plainid.models.context.request_context import RequestContext
```
3. Initialize dependencies:

```
permissions_provider = PlainIDPermissionsProvider(
    base_url="https://platform-product.us1.plainid.io",
    client_id="your_client_id",
    client_secret="your_client_secret",
)

categorizer = Categorizer(
    classifier_provider=classifier,
    permissions_provider=permissions_provider,
    all_categories=["contract", "HR", "finance"],
)
```
4. Define the RequestContext:

```
request_context = RequestContext(
    entity_id="your_entity_id",
    entity_type_id="your_entity_type",
)
```
5. Run categorization:

```
result = await categorizer.acategorize(
    "I'd like to know the weather forecast for today",
    request_context=request_context,
)
```

## Category Classifiers

Two built-in classifiers are available.

**LLMCategoryClassifierProvider** Uses an LLM to classify prompts. Model calls are powered by LiteLLM, which supports multiple LLM providers through a unified interface.

```
# OpenAI
export OPENAI_API_KEY="your_openai_api_key"

# Anthropic
export ANTHROPIC_API_KEY="your_anthropic_api_key"

# Azure OpenAI
export AZURE_API_KEY="your_azure_api_key"
export AZURE_API_BASE="https://your-resource.openai.azure.com"
export AZURE_API_VERSION="2024-02-01"
```

```
from core_plainid.categorization.llm_category_classifier_provider import LLMCategoryClassifierProvider

llm_classifier = LLMCategoryClassifierProvider(model="openai/gpt-4o")
```

The model parameter follows LiteLLM naming conventions. Classification quality depends on the selected model. Prefer larger or specialized models for better results.

**ZeroShotCategoryClassifierProvider** Uses a Hugging Face zero-shot classification model. The model is downloaded automatically on first use.

```
from core_plainid.categorization.zeroshot_category_classifier_provider import ZeroShotCategoryClassifierProvider

zeroshot_classifier = ZeroShotCategoryClassifierProvider(
    model_name="facebook/bart-large-mnli",
    threshold=0.5,
)
```

The `threshold` parameter default is 0.5 and controls the minimum confidence score required for a category to be included. Use this classifier if you want better classification results without relying on an external LLM API, but note it requires disk space for the downloaded model.

## Anonymization

The PresidioAnonymizer detects and anonymizes PII in text using Microsoft Presidio. It supports two actions: MASK (replaces PII with ***) and ENCRYPT (encrypts the detected PII using a provided key).

**PlainID Setup** To use anonymization, configure Rulesets in PlainID using the Output_Control template.

**To configure anonymization Rulesets:**

1. Define a Ruleset for each entity type:

```
# METADATA
# custom:
#   plainid:
#     kind: Ruleset
#     name: PERSON
ruleset(asset, identity, requestParams, action) if {
    asset.template == "Output_Control"
    asset["path"] == "PERSON"
    action.id in ["MASK"]
}
```
2. Configure custom regex entities in PlainID with a REGEX path prefix and a regexValue attribute containing the pattern:

```
# METADATA
# custom:
#   plainid:
#     kind: Ruleset
#     name: REGEX_EMAIL
ruleset(asset, identity, requestParams, action) if {
    asset.template == "Output_Control"
    asset["path"] == "REGEX_EMAIL"
    asset["regexValue"] == "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}"
    action.id in ["MASK"]
}
```
3. Configure AHDS entities as an example:

```
# METADATA
# custom:
#   plainid:
#     kind: Ruleset
#     name: DOCTOR
ruleset(asset, identity, requestParams, action) if {
    asset.template == "Output_Control"
    asset["path"] == "DOCTOR"
    action.id in ["MASK"]
}
```

For medical or health data, you can enable Azure Health Data Services de-identification to detect PHI entities such as DOCTOR, PATIENT, and AGE. Configure them in PlainID the same way.

To use anonymization in your application:

1. Initialize the PresidioAnonymizer:

```
from core_plainid.anonymization.presidio_anonymizer import PresidioAnonymizer
from core_plainid.utils.plainid_permissions_provider import PlainIDPermissionsProvider
from core_plainid.models.context.request_context import RequestContext

permissions_provider = PlainIDPermissionsProvider(
    base_url="https://platform-product.us1.plainid.io",
    client_id="your_client_id",
    client_secret="your_client_secret",
)

anonymizer = PresidioAnonymizer(
    permissions_provider=permissions_provider,
    encrypt_key="your_16_char_key!",
)
```
2. Define the RequestContext:

```
request_context = RequestContext(
    entity_id="your_entity_id",
    entity_type_id="your_entity_type",
)
```
3. Run anonymization:

```
result = await anonymizer.aanonymize(
    "John Smith lives in New York",
    request_context=request_context,
)
print(result)
```

The `encrypt_key` parameter is optional and only required if you use the ENCRYPT action. The key is used for AES encryption and must be 128, 192, or 256 bits long (16, 24, or 32 characters).

**To enable Azure Health De-identification (AHDS) (example):**

1. Set the required environment variables:

```
export AHDS_ENDPOINT="https://your-deid-service.api.deid.azure.com"
export AZURE_TENANT_ID="your_azure_tenant_id"
export AZURE_CLIENT_ID="your_azure_client_id"
export AZURE_CLIENT_SECRET="your_azure_client_secret"
```
2. Enable AHDS in the anonymizer:

```
anonymizer = PresidioAnonymizer(
    permissions_provider=permissions_provider,
    encrypt_key="your_16_char_key!",
    enable_ahds=True,
)
```

## SQL Database Authorizer

The PlainIDSQLAuthorizerClient dynamically modifies SQL queries based on authorization Policies, enforcing Row-Level Security and Column-Level Security at query time.

Note: This component supports only a single identity per request.

Authentication The client supports two authentication modes:

- Client credentials provide `client_id` and `client_secret` at construction time.
- JWT token provides an `auth_token` per request. The Bearer prefix is added automatically if missing.

Refer to our [API Client Credentials](/docs/environment-settings#api-client-credentials) documentation for more information about client credentials.

**To use the SQL Authorizer:**

1. Initialize the client:

```
from core_plainid.clients.plainid_sql_authorizer_client import PlainIDSQLAuthorizerClient
from core_plainid.models.request.sql_authorizer_request import (
    SQLAuthorizerRequest,
    SQLAuthorizerFlags,
    PoliciesJoinOperation,
)

sql_authorizer = PlainIDSQLAuthorizerClient(
    base_url="https://your-sql-authz.plainid.cloud",
    client_id="your_client_id",
    client_secret="your_client_secret",
)
```
2. Create the request:

```
request = SQLAuthorizerRequest(
    sql="SELECT * FROM accounts WHERE country = 'US'",
    entity_id="your_entity_id",
    entity_type_id="your_entity_type",
    flags=SQLAuthorizerFlags(
        empty_rls_treat_as_denied=True,
        empty_cls_treat_as_permitted=True,
        expand_star_column=True,
        policies_join_operation=PoliciesJoinOperation.OR,
    ),
)
```
3. Execute authorization:

```
response = sql_authorizer.authorize_sql(request)
print(response.sql)
print(response.was_modified)
```
4. Optionally, use JWT authentication per request:

```
sql_authorizer = PlainIDSQLAuthorizerClient(
    base_url="https://your-sql-authz.plainid.cloud",
    client_id="your_client_id",
)

response = sql_authorizer.authorize_sql(request, auth_token="your_jwt_token")
```
