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

# fjall user

> Declare organisation users and group memberships in code, then apply them with an organisation deploy.

<Info>
  **Users and access are declared in code.** The `fjall user` verbs edit the
  `identityCentre` block of `fjall/organisation/infrastructure.ts` — they never
  call AWS directly. Changes take effect when you run `fjall deploy
      organisation`.
</Info>

## Overview

Your organisation's users, groups, and memberships live in the `identityCentre`
config of your organisation infrastructure file. The `fjall user` verbs are
safe, reviewable file editors: they modify the declaration, you commit the
diff, and the next organisation deploy makes AWS IAM Identity Center match it.

```bash theme={null}
fjall user add sarah@example.com --group AdministratorAccess
fjall deploy organisation
```

Because the verbs edit a local file, they need **no AWS credentials and no
login** — authentication applies where it always did, at `fjall deploy
organisation`. Only `fjall user list --live` and `fjall user add --live` touch
AWS, read-only.

## Identity source modes

The `identityCentre` config declares where user objects come from. The verbs
adapt to the declared mode:

| Mode              | Who owns user objects                             | What `fjall user add` writes                                        |
| ----------------- | ------------------------------------------------- | ------------------------------------------------------------------- |
| `fjall-managed`   | Fjall (native Identity Center directory)          | A `users` entry plus the group membership                           |
| `external`        | Your IdP (Google Workspace, Okta, Entra) via SCIM | The group membership only — user details are rejected with guidance |
| `external-manual` | Your IdP via SAML, mirrored manually in AWS       | The membership, plus an optional pre-provisioned `users` entry      |

See [Users and Permissions](/deployment/users-and-permissions) for the config
shapes and how to choose a mode.

## Subcommands

### Add a user or membership

```bash theme={null}
fjall user add <email> --group <group>
```

| Option                  | Description                                                                                          |
| ----------------------- | ---------------------------------------------------------------------------------------------------- |
| `--group <group>`       | Group to add the membership to                                                                       |
| `--first <name>`        | Given name — declares the user entry (`fjall-managed` / `external-manual`)                           |
| `--last <name>`         | Family name — declares the user entry                                                                |
| `--expires <timestamp>` | ISO 8601 expiry for the user's access (contractors)                                                  |
| `--live`                | Verify the email against the live identity store before writing (needs organisation AWS credentials) |

In `external` mode, `--first`/`--last` are a hard error — your IdP owns user
details. The default add is a pure file edit; pass `--live` to opt in to a
preflight that checks the email is already synced into the identity store.

After a successful write, the CLI offers to run the organisation deploy for
you (identity-only organisation deploys typically take 2–5 minutes). Decline
and the change simply waits in your working tree for review.

### Remove a user or membership

```bash theme={null}
fjall user remove <email>                    # removes the user and every membership
fjall user remove <email> --group <group>    # removes only that membership
```

### List declared users

```bash theme={null}
fjall user list
```

A pure file read — shows every declared user and membership, including
membership-only entries (emails that appear in groups without a `users`
entry), names, groups, and any `expires` stamps.

```bash theme={null}
fjall user list --live
```

Adds live drift columns by querying the identity store read-only: whether each
email is synced (`in-store` / `not-synced`) and any declared memberships that
are not yet live in AWS (pending deploy, or stale after an IdP change).
Requires organisation AWS credentials.

### Re-resolve external users

```bash theme={null}
fjall user rebind
```

Bumps `resolutionVersion` in the config so every email lookup re-resolves on
the next deploy. Use this when your IdP deleted and recreated a user (the
underlying user ID rotated) and memberships need to re-bind to the new ID.

## Setting up an identity source

If your identity store isn't set up yet, the verbs fail with a prescriptive
error rather than a generic AWS one:

| Code                      | Meaning                                       | Fix                                                                |
| ------------------------- | --------------------------------------------- | ------------------------------------------------------------------ |
| `IDC_NO_INSTANCE`         | No Identity Center instance exists            | Run `fjall org identity setup-google` (console enablement runbook) |
| `IDC_SCIM_NOT_CONFIGURED` | `external` mode but no SCIM-provisioned users | Run `fjall org identity setup-google` to connect auto-provisioning |
| `IDC_USER_NOT_SYNCED`     | SCIM works but this email hasn't arrived      | Check the Google-side app assignment; sync can take up to 24 hours |

For Google Workspace, the guided runbook walks the whole SAML + SCIM
connection:

```bash theme={null}
fjall org identity setup-google          # guided steps
fjall org identity setup-google --wait   # …then poll until the first user syncs
```

## Default groups

Organisations deploy with three standard groups. Add custom groups and
permission sets in the `identityCentre` config — see
[Users and Permissions](/deployment/users-and-permissions).

| Group                 | Description                 | AWS Permissions        |
| --------------------- | --------------------------- | ---------------------- |
| `AdministratorAccess` | Full administrative access  | All AWS services       |
| `ReadOnlyAccess`      | View-only access            | Read all resources     |
| `Billing`             | Billing and cost management | Cost Explorer, Budgets |

If a deploy finishes and every group is memberless, the deploy summary
reminds you to declare access with `fjall user add <email> --group <group>`.

## Common workflows

### Onboard a teammate (external IdP)

```bash theme={null}
fjall user add sarah@example.com --group AdministratorAccess
fjall deploy organisation
```

Sarah signs in through your IdP; the deploy grants her group's access across
your accounts.

### Grant a contractor time-boxed access

```bash theme={null}
fjall user add contractor@agency.com --group ReadOnlyAccess --expires 2026-09-30T00:00:00Z
fjall deploy organisation
```

Past-expiry users still present in a membership fail the deploy at synth time,
so expired access can't silently persist.

### Remove all access

```bash theme={null}
fjall user remove leaver@example.com
fjall deploy organisation
```

### Audit declared vs live access

```bash theme={null}
fjall user list --live
```

## Breaking change: SDK verbs removed

From fjall 2.24, the imperative verbs that wrote directly to AWS
(`user create`, `user destroy`, `user associate`, `user dissociate`) are
removed, along with the deprecated `fjall user token` alias. Their
replacements:

| Removed                         | Use instead                                 |
| ------------------------------- | ------------------------------------------- |
| `fjall user create`             | `fjall user add <email> --first … --last …` |
| `fjall user destroy <username>` | `fjall user remove <email>`                 |
| `fjall user associate <u> <g>`  | `fjall user add <email> --group <group>`    |
| `fjall user dissociate <u> <g>` | `fjall user remove <email> --group <group>` |
| `fjall user token *`            | [`fjall token *`](/cli/token)               |

All replacements are file edits — follow each with `fjall deploy
organisation` to apply.

## Next steps

<CardGroup cols={2}>
  <Card title="Users and Permissions" icon="shield" href="/deployment/users-and-permissions">
    The identityCentre config: modes, groups, permission sets, memberships.
  </Card>

  <Card title="fjall token" icon="key" href="/cli/token">
    Issue and manage agent tokens for CI/CD and automation.
  </Card>

  <Card title="fjall deploy" icon="rocket" href="/cli/deploy">
    Apply declared changes with an organisation deploy.
  </Card>

  <Card title="Agent Mode" icon="robot" href="/cli/agent-mode">
    Drive these verbs from AI agents with structured output.
  </Card>
</CardGroup>
