# Personas Overview

Personas provide role-based access control for MCP tools. Each persona defines which tools a user can access and can include custom prompts and hints for the AI assistant.

## What Is a Persona?

A persona is a named configuration that includes:

- **Display Name** - Human-readable identifier
- **Roles** - Which authenticated roles map to this persona
- **Tool Rules** - Allow and deny patterns for tool access
- **Context Overrides** - Per-persona customization of platform description and agent instructions

## How Personas Work

```mermaid
graph LR
    A[Authenticated User] --> B{Role Mapper}
    B --> C[Analyst Persona]
    B --> D[Admin Persona]
    B --> E[Custom Persona]

    C --> F[Tool Filter]
    D --> F
    E --> F

    F --> G[Allowed Tools]
```

1. User authenticates (OIDC or API key)
2. Roles are extracted from credentials
3. Role mapper finds the matching persona
4. Tool filter applies allow/deny rules
5. Only permitted tools are available

## Configuration

Define personas in your configuration:

```yaml
personas:
  definitions:
    analyst:
      display_name: "Data Analyst"
      description: "Read-only access to query and explore data"
      roles: ["analyst", "data_user"]
      tools:
        allow:
          - "trino_*"
          - "datahub_*"
        deny:
          - "*_delete_*"
      context:
        description_prefix: "You are helping a data analyst explore data."

    admin:
      display_name: "Administrator"
      description: "Full access to all tools"
      roles: ["admin", "platform_admin"]
      tools:
        allow: ["*"]
        deny: []

    viewer:
      display_name: "Viewer"
      description: "Read-only access, no queries"
      roles: ["viewer", "guest"]
      tools:
        allow:
          - "datahub_search"
          - "datahub_get_*"
          - "s3_list_*"
          - "s3_get_object_metadata"
        deny:
          - "trino_query"
          - "trino_execute"
          - "s3_get_object"

  default_persona: viewer
```

## Default Persona

The `default_persona` is used when:

- Authentication is disabled
- User has no roles that match any persona
- An anonymous request is made

```yaml
personas:
  default_persona: viewer    # Fall back to viewer for unknown users
```

## Built-in Personas

The platform includes two built-in personas that can be overridden:

**Default Persona:**
```yaml
default:
  display_name: "Default User"
  roles: []
  tools:
    allow: ["*"]
    deny: []
```

**Admin Persona:**
```yaml
admin:
  display_name: "Administrator"
  roles: ["admin"]
  tools:
    allow: ["*"]
    deny: []
  priority: 100
```

## Persona Priority

When a user has roles matching multiple personas, priority determines which one is used:

```yaml
personas:
  definitions:
    analyst:
      roles: ["analyst"]
      priority: 10

    senior_analyst:
      roles: ["analyst", "senior"]
      priority: 20    # Higher priority wins

    admin:
      roles: ["admin"]
      priority: 100   # Admin always wins if user has admin role
```

A user with roles `["analyst", "senior"]` gets the `senior_analyst` persona (higher priority).

## Context Overrides

Personas can include context overrides that customize the platform description and agent instructions returned by the `platform_info` tool:

```yaml
analyst:
  context:
    description_prefix: |
      You are helping a data analyst. Focus on:
      - Data exploration and analysis
      - SQL best practices
      - Statistical insights

    agent_instructions_suffix: |
      When writing SQL:
      - Use meaningful aliases
      - Add comments for complex logic
      - Limit results to avoid overwhelming output
      Always explain query results in business terms.
```

### Override Fields

| Field | Effect |
|-------|--------|
| `description_prefix` | Prepended to the platform description |
| `description_override` | Replaces the platform description entirely |
| `agent_instructions_suffix` | Appended to the platform agent instructions |
| `agent_instructions_override` | Replaces the platform agent instructions entirely |

Override fields (`description_override`, `agent_instructions_override`) take precedence over prefix/suffix fields. If both a prefix and an override are set, only the override is used.

## Connection Access Control

Personas can restrict which toolkit connections a user may access. This is enforced at the `tools/call` level: a tool call must pass both the tool pattern check and the connection check.

```yaml
personas:
  definitions:
    analyst:
      display_name: "Data Analyst"
      roles: ["analyst"]
      tools:
        allow: ["trino_*", "datahub_*"]
      connections:
        allow: ["prod-*"]
        deny: ["prod-admin-*"]

    admin:
      display_name: "Administrator"
      roles: ["admin"]
      tools:
        allow: ["*"]
      # No connections block = all connections allowed
```

### How Connection Filtering Works

1. When a tool call arrives, the middleware identifies which toolkit connection the tool belongs to
2. The user's persona connection rules are evaluated: deny patterns are checked first, then allow patterns
3. If the connection is denied (or not allowed), the tool call is rejected

If the `connections` block is omitted or both `allow` and `deny` are empty, all connections are permitted. This preserves backward compatibility with existing configurations.

### Pattern Syntax

Connection patterns use the same wildcard syntax as tool patterns:

- `*` matches any sequence of characters
- `prod-*` matches `prod-trino`, `prod-datahub`, etc.
- `*-readonly` matches `trino-readonly`, `datahub-readonly`, etc.

## Knowledge Tool Access

The knowledge capture tools follow the same allow/deny patterns. Control who can capture insights and who can apply them:

```yaml
personas:
  definitions:
    analyst:
      display_name: "Data Analyst"
      roles: ["analyst"]
      tools:
        allow:
          - "trino_*"
          - "datahub_*"
          - "capture_insight"       # Can capture knowledge
        deny:
          - "apply_knowledge"       # Cannot apply changes

    admin:
      display_name: "Administrator"
      roles: ["admin"]
      tools:
        allow: ["*"]               # Full access including apply_knowledge

    etl_service:
      display_name: "ETL Service"
      roles: ["service"]
      tools:
        allow:
          - "trino_*"
        deny:
          - "capture_insight"       # Automated processes should not capture
          - "apply_knowledge"
```

See [Knowledge Capture](../knowledge/overview.md) for the full feature documentation.

## Example: Data Mesh Personas

```yaml
personas:
  definitions:
    sales_analyst:
      display_name: "Sales Domain Analyst"
      roles: ["sales_team"]
      tools:
        allow:
          - "trino_*"
          - "datahub_*"
        deny: []
      context:
        description_prefix: |
          You are helping a sales analyst.
          Focus on: revenue metrics, customer data, order patterns.
        agent_instructions_suffix: "Query the hive.sales schema for sales data."

    marketing_analyst:
      display_name: "Marketing Domain Analyst"
      roles: ["marketing_team"]
      tools:
        allow:
          - "trino_*"
          - "datahub_*"
        deny: []
      context:
        description_prefix: |
          You are helping a marketing analyst.
          Focus on: campaign metrics, customer segments, attribution.
        agent_instructions_suffix: "Query the hive.marketing schema for marketing data."

  default_persona: viewer
```

## Next Steps

- [Tool Filtering](tool-filtering.md) - Allow/deny pattern syntax
- [Role Mapping](role-mapping.md) - Map OIDC roles to personas
