# scim

Source: https://permdock.com/docs/cli/scim

permdock scim generate writes the Postgres tables postgresDirectoryStore keeps a SCIM directory in, with every row keyed on its tenant and userName and externalId unique per tenant.

```bash
permdock scim generate [--out <file>] [--dialect supabase|neon|guc] [--schema <name>] [--check] [--dry-run]
```

`generate` writes one SQL file with three tables in the helper schema: `scim_users`, `scim_groups` and `scim_group_members`, each keyed on `(tenant, id)`. [`postgresDirectoryStore`](/docs/adapters/scim#postgres-store) reads and writes them for `scimHandler`, so one endpoint serves every tenant the Cloud relay or an identity provider provisions. The command reads no policy; it reads `rls.dialect` and `rls.schema` from the config when the flags are absent.

```sql
-- generated by permdock scim generate (--dialect supabase)
-- the SCIM directory postgresDirectoryStore reads and writes for scimHandler; every row belongs to one tenant
create schema if not exists "permdock";

create table if not exists "permdock"."scim_users" (
  seq bigint generated always as identity unique,
  tenant text not null check (tenant <> ''),
  id text not null check (id <> ''),
  user_name text not null,
  external_id text,
  -- active, emails, x, created_at, updated_at, revision
  primary key (tenant, id),
  constraint "scim_users_user_name_key" unique (tenant, user_name),
  constraint "scim_users_external_id_key" unique (tenant, external_id)
);
-- "permdock"."scim_groups" and "permdock"."scim_group_members" follow

alter table "permdock"."scim_users" enable row level security;
revoke all on table "permdock"."scim_users", "permdock"."scim_groups", "permdock"."scim_group_members" from public, anon, authenticated;
```

| Flag | Values | Default | Effect |
| --- | --- | --- | --- |
| `--out` | a path, or `-` for stdout | `supabase/schemas/<schema>/scim.sql` for Supabase, else `permdock_scim.sql` | Where the SQL goes |
| `--dialect` | `supabase`, `neon`, `guc` | `rls.dialect`, else `supabase` | The client roles the tables are revoked from: `anon` and `authenticated`, `anonymous` and `authenticated`, or only `public` |
| `--schema` | an identifier | `rls.schema`, else `permdock` | The schema of the tables; pass the same `schema` to `postgresDirectoryStore` |
| `--check` | flag | off | Exit `1` when the file on disk differs, with a diff; write nothing |
| `--dry-run` | flag | off | Print the file that would be created or updated; write nothing |

The SQL never names `service_role`. Grant the role `postgresDirectoryStore` connects as `select`, `insert`, `update` and `delete` on the three tables when it does not own them. `--json` puts `out`, `dialect`, `schema`, `tables` and the written `files` in `data`.

## Side effects [#side-effects]

What each command may change; [side effects](/docs/cli#side-effects) explains each one.

| Command | Side effects |
| --- | --- |
| `permdock scim generate` | `files` |

## Why [#why]

The SCIM adapter page owns the design: why the command writes tenant-keyed tables and a store rather than a membership mapping ([SCIM](/docs/adapters/scim#why)). The tables are revoked from the data API's roles because only `scimHandler`, authenticated as the identity provider or the relay, may change them; a client that could write a group row could grant itself that group's roles.
