# `PhoenixKit.API.ServiceUsers`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v3.5.0/lib/phoenix_kit/api/service_users.ex#L1)

Service users: accounts that exist only to own API keys.

A service user is an ordinary `phoenix_kit_users` row with `api_only: true`, a
non-deliverable address `api-<uuid>@service.invalid` (the `.invalid` TLD never
resolves) and a random password hash nobody knows. It holds the roles its
creator chose, so a key owned by it is limited by those roles' permissions
exactly as a key owned by a person is. Every web authentication entry point
refuses `api_only` users (see the `api_only` guards in `PhoenixKit.Users.Auth`
and `PhoenixKitWeb.Users.Auth`), so the account can never obtain a session.

## Which roles a creator may give

Only roles whose permissions are a **subset of the creator's own**, and never
the Owner role. An `api` holder with narrow rights therefore cannot build a
more powerful identity than themselves.

The user is created directly, not through `Auth.register_user/2`: that path
would promote it to Owner on an install without one, add the default `User`
role, send mail and rate-limit the creator.

# `allowed_roles`

```elixir
@spec allowed_roles(PhoenixKit.Users.Auth.Scope.t()) :: [PhoenixKit.Users.Role.t()]
```

The roles the person behind `creator_scope` may give to a service user: not the
Owner role, and only roles whose permissions the creator holds in full. Empty
for someone who does not hold `api`.

# `create`

```elixir
@spec create(PhoenixKit.Users.Auth.Scope.t(), %{
  optional(:name) =&gt; String.t(),
  roles: [String.t()]
}) ::
  {:ok, PhoenixKit.Users.Auth.User.t()}
  | {:error, :forbidden | :role_not_allowed | Ecto.Changeset.t()}
```

Creates a service user holding `roles` (a list of role names) on behalf of the
person behind `creator_scope`.

`attrs` takes `roles` and an optional `name` (shown in the user list).

Errors: `:forbidden` when the creator does not hold `api`;
`:role_not_allowed` when any role is unknown, is the Owner role or carries a
permission the creator lacks (nothing is created); a changeset when the name is
invalid.

# `list`

```elixir
@spec list(PhoenixKit.Users.Auth.Scope.t()) :: [PhoenixKit.Users.Auth.User.t()]
```

The service users the person behind `scope` may see and hand keys to: all of
them for an Owner, the ones they created for any other holder of `api`, none
for someone without `api`. Oldest first.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
