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

# Per-customer isolation with environments

> Multi-tenant pattern: one environment per customer, one API key per environment.

If you're building a product where each of your customers has their own
knowledge base, you need strict isolation so Customer A's documents never
appear in Customer B's queries. Memic's environments are built for exactly
this.

## The pattern

1. **One environment per customer.** When a customer signs up, create a new
   environment in your Memic project.
2. **One API key per environment.** Each environment gets its own key.
3. **Store the key mapping server-side.** In your own database, map each
   customer to their Memic API key.
4. **Swap keys per request.** On every request, load the authenticated
   user's customer record, look up their Memic key, instantiate a Memic
   client with that key.

Because every Memic API key is cryptographically bound to exactly one
environment, customer data **cannot leak** — even if your code has bugs.
Using the wrong key just fails; it can't accidentally read from a different
environment.

## Schema

Your database needs something like:

```sql theme={null}
CREATE TABLE customers (
  id UUID PRIMARY KEY,
  name TEXT NOT NULL,
  memic_environment_id UUID NOT NULL,
  memic_api_key_encrypted TEXT NOT NULL,  -- encrypted at rest
  created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
```

Store API keys encrypted — use your cloud's secret manager or an app-level
encryption key.

## Provisioning flow

When a new customer signs up:

```python theme={null}
def provision_customer(db, customer_name: str) -> Customer:
    # 1. Create the environment in Memic
    env = memic_admin.environments.create(
        project_id=MEMIC_PROJECT_ID,
        slug=f"customer-{slugify(customer_name)}",
        name=customer_name,
    )

    # 2. Create an API key scoped to that environment
    key = memic_admin.api_keys.create(
        environment_id=env.id,
        name=f"{customer_name} production key",
    )

    # 3. Store in your DB
    customer = Customer(
        name=customer_name,
        memic_environment_id=env.id,
        memic_api_key_encrypted=encrypt(key.value),
    )
    db.add(customer)
    db.commit()

    return customer
```

<Info>
  Environment and API key creation uses Memic's management API. This is not
  part of the public `/api/v1/*` surface — contact Memic for access to the
  management API if you need to automate provisioning.
</Info>

## Request flow

```python theme={null}
from fastapi import FastAPI, Depends
from memic import Memic

app = FastAPI()


def get_memic_client(current_user = Depends(get_current_user)) -> Memic:
    """Returns a Memic client scoped to the current user's customer."""
    customer = db.get_customer(current_user.customer_id)
    key = decrypt(customer.memic_api_key_encrypted)
    return Memic(api_key=key)


@app.post("/search")
def search(
    query: str,
    memic: Memic = Depends(get_memic_client),
):
    return memic.search(query)
```

Every request to `/search` uses a fresh Memic client bound to the
authenticated user's customer environment. Cross-tenant queries are
structurally impossible.

## Testing the isolation

In your test suite, assert that cross-customer queries return nothing:

```python theme={null}
def test_customer_isolation():
    # Upload a file to Customer A's environment
    client_a = Memic(api_key=customer_a_key)
    client_a.files.upload("./a-secret.pdf")

    # Query from Customer B's environment — should return 0 results
    client_b = Memic(api_key=customer_b_key)
    results = client_b.search("a secret")
    assert len(results.semantic) == 0
```

This test is fast and should run on every commit. If it ever fails, you've
misconfigured environment scoping somewhere.

## Going further

* **Key rotation**: when a customer asks to rotate, create a new key,
  update your DB, delete the old key in the Memic dashboard
* **Soft-deleting customers**: don't delete the Memic environment until
  your compliance/retention window expires; then delete via the dashboard
* **Analytics**: aggregate per-customer stats in your own DB rather than
  trying to slice Memic's usage — Memic doesn't expose per-environment
  usage metrics in the public API
