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

# Security & Tenancy

> Authentication, authorization, isolation, and operational safeguards

Mixpeek enforces organization-level authentication, namespace isolation, and stage-level validation across the entire stack. This page summarizes the security model and operational protections you should configure in production.

## Authentication

* **Header**: `Authorization: Bearer <api_key>`
* API keys belong to an organization; keys can be rotated, revoked, or scoped per environment.
* Sensitive operations (e.g., creating namespaces, rotating keys) require elevated permissions.

See [API Keys](/operations/api-keys) for the full lifecycle: creating keys, setting `read`/`write`/`delete`/`admin` permissions and resource scopes, rotating and revoking, per-key rate limits, usage attribution, and end-user (`principal_id`) keys.

## Namespace Isolation

* **Header**: `X-Namespace: <namespace_id or namespace_name>`
* Every MongoDB query filters on `namespace_id`; indexes ensure isolation at scale.
* [MVS](https://mixpeek.com/mvs) uses one namespace per namespace (`ns_<namespace_id>`); payload filters ensure cross-namespace safety.
* Redis cache keys and Ray job metadata include namespace identifiers.

### Dual Identifier Model

| Identifier        | Visible? | Purpose                                    |
| ----------------- | -------- | ------------------------------------------ |
| `organization_id` | Yes      | User-facing identifier in API responses    |
| `internal_id`     | No       | Primary key for service-to-service lookups |
| `namespace_id`    | Yes      | Isolation boundary for data and compute    |

Keep `internal_id` secret; it is intentionally absent from public APIs.

## Authorization & Rate Limits

* Routes declare required permission levels (`read`, `write`, `delete`, `admin`).
* Rate limits enforced via Redis middleware; set per-plan and per-route to protect backends.
* Tasks and retriever executions are metered in dollars; analytics endpoints expose usage metrics for billing reconciliation.

## Secrets & Credentials

Mixpeek provides an encrypted secrets vault for storing sensitive credentials like API keys. Secrets are encrypted at rest using Fernet symmetric encryption and are never exposed in API responses.

### Organization Secrets Vault

Store and manage secrets via the API:

<CodeGroup>
  ```bash Create a Secret theme={null}
  curl -X POST "https://api.mixpeek.com/v1/organizations/secrets" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "secret_name": "openai_api_key",
      "secret_value": "sk-proj-abc123..."
    }'
  ```

  ```bash List Secrets theme={null}
  # Returns secret names only - values are never exposed
  curl "https://api.mixpeek.com/v1/organizations/secrets" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```bash Update a Secret theme={null}
  curl -X PUT "https://api.mixpeek.com/v1/organizations/secrets/openai_api_key" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "secret_value": "sk-proj-new-key..."
    }'
  ```

  ```bash Delete a Secret theme={null}
  curl -X DELETE "https://api.mixpeek.com/v1/organizations/secrets/openai_api_key" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```
</CodeGroup>

### Bring Your Own Key (BYOK)

Use your own LLM API keys instead of Mixpeek's default keys. This gives you:

| Benefit          | Description                                   |
| ---------------- | --------------------------------------------- |
| **Cost Control** | Use your own LLM provider account and billing |
| **Rate Limits**  | Use your own rate limits instead of shared    |
| **Compliance**   | Keep API calls under your own account         |
| **Key Rotation** | Rotate keys without modifying retrievers      |

#### Supported Providers

| Provider  | Secret Name Example | Models                                         |
| --------- | ------------------- | ---------------------------------------------- |
| OpenAI    | `openai_api_key`    | gpt-4o, gpt-4o-mini                            |
| Anthropic | `anthropic_api_key` | claude-3-haiku, claude-3-sonnet, claude-3-opus |
| Google    | `google_api_key`    | gemini-3.1-flash-lite, gemini-2.5-pro          |

#### Apply a Key to All LLM Operations

The fastest way to use your own key is to set it as the **organization-wide default**. Once configured, it automatically applies to every LLM operation — extractors, retrievers, clustering, taxonomy inference, and manifest generation — with no per-stage configuration needed.

<Steps>
  <Step title="Store your key in the secrets vault">
    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST "https://api.mixpeek.com/v1/organizations/secrets" \
        -H "Authorization: Bearer YOUR_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "secret_name": "openai_api_key",
          "secret_value": "sk-proj-abc123..."
        }'
      ```

      ```python Python theme={null}
      from mixpeek import Mixpeek

      mx = Mixpeek(api_key="YOUR_API_KEY")
      mx.organizations.secrets.create(
          secret_name="openai_api_key",
          secret_value="sk-proj-abc123..."
      )
      ```
    </CodeGroup>
  </Step>

  <Step title="Set it as the org-wide default for that provider">
    <CodeGroup>
      ```bash cURL theme={null}
      curl -X PATCH "https://api.mixpeek.com/v1/organizations" \
        -H "Authorization: Bearer YOUR_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "default_llm_credentials": {
            "openai": "openai_api_key"
          }
        }'
      ```

      ```python Python theme={null}
      mx.organizations.update(
          default_llm_credentials={
              "openai": "openai_api_key"
          }
      )
      ```
    </CodeGroup>
  </Step>
</Steps>

You can configure defaults for multiple providers at once:

```json theme={null}
{
  "default_llm_credentials": {
    "openai": "my_openai_key",
    "anthropic": "my_anthropic_key",
    "google": "my_gemini_key"
  }
}
```

<Tip>
  You can also do this from Studio: when creating a secret, toggle **"Use as default LLM key"** and it will automatically be applied org-wide for the detected provider.
</Tip>

<Note>
  Values in `default_llm_credentials` are **secret names** (not raw API keys). The actual keys are stored encrypted in your secrets vault and resolved at runtime.
</Note>

#### Override a Key on a Specific Stage

If you need a different key for a particular retriever stage, extractor, or cluster config, set `api_key` directly using the `{{secrets.name}}` template syntax. This overrides the org-wide default for that operation only.

```json theme={null}
{
  "stages": [
    {
      "stage_name": "llm_enrich",
      "stage_type": "enrich",
      "config": {
        "stage_id": "llm_enrich",
        "parameters": {
          "provider": "openai",
          "model": "gpt-4o-mini",
          "prompt": "Summarize this document.",
          "output_field": "summary",
          "api_key": "{{secrets.openai_api_key}}"
        }
      }
    }
  ]
}
```

#### Credential Resolution Order

Mixpeek resolves LLM credentials in this order (highest priority first):

1. **Per-resource** `api_key` / `{{secrets.name}}` — explicit key on a specific stage or extractor
2. **Organization default** — set once via `default_llm_credentials`, applied everywhere
3. **Mixpeek platform keys** — used when no custom key is configured (usage charged to your Mixpeek account)

#### Security

* **Encryption at rest**: All secrets are encrypted using Fernet symmetric encryption with a dedicated encryption key
* **Zero exposure**: Secret values are never returned in API responses — only secret names are visible
* **Per-request resolution**: Credentials are decrypted on-demand for each LLM call, not cached globally
* **No cross-tenant leakage**: Each organization's credentials are isolated; provider instances with custom keys are never shared between organizations
* **Audit trail**: Secret access and organization configuration changes are logged for compliance

### Security Best Practices

* **Rotate credentials regularly** – Update secrets via the API without changing retriever configurations
* **Use IAM roles** – For S3/GCS access, prefer IAM roles over long-lived access keys
* **Audit access logs** – Monitor secret access patterns for anomalies
* **Scope API keys** – Issue environment-specific Mixpeek API keys (dev, staging, prod)

## Data Protection

* **Storage**: rely on encryption at rest provided by MongoDB Atlas, [MVS](https://mixpeek.com/mvs), or your infrastructure.
* **Transit**: require TLS for API endpoints and Ray Serve; use mTLS or network policies for cross-service traffic when available.
* **Backups**: configure automated backups for MongoDB and MVS; version S3 buckets with lifecycle policies.

## Operational Safeguards

* Enable `/v1/health` probes in load balancers to route around unhealthy instances.
* Use webhooks to detect ingestion completion; failed webhook deliveries remain retriable in MongoDB.
* Monitor rate-limit counters and task failure rates to spot abusive or buggy clients.
* Log request IDs and namespace IDs to correlate incidents quickly.

## Hardening Checklist

1. **Network** – restrict API access to trusted origins, configure CORS, and use private networking for backend services.
2. **Auth** – issue scoped API keys, expire unused keys, enable audit logging.
3. **Secrets** – manage via Vault, AWS Secrets Manager, GCP Secret Manager, or Kubernetes secrets with rotation.
4. **Tenancy** – adopt one namespace per environment/tenant; enforce `X-Namespace` always.
5. **Monitoring** – alert on health endpoint status, rate-limit breaches, or repeated 401/403 responses.

## References

* [API Keys](/operations/api-keys)
* [Namespaces](/ingestion/namespaces)
* [Observability](/operations/observability)
* [Webhooks](/operations/webhooks)
* [Tasks](/processing/tasks)
* [Health Check](/api-reference/health/healthcheck)
