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

# Identities

> A platform-owned directory of the people, groups, and accounts your customer-facing AI agents talk to — and the scope that controls what data each one can read.

<Warning>
  **Experimental — not yet generally available.** Identities power customer-facing AI agents and
  aren't enabled by default. If you'd like to try them on your organization, email
  [support@stardeck.ai](mailto:support@stardeck.ai) and we'll turn the feature on for you. The
  concepts and UI described here work today, but details may change before general release.
</Warning>

An **identity** is a customer or contact in your organization's directory — the *subject* a
conversation is about. When a customer-facing AI agent handles a chat, it reads app data **scoped
to that conversation's identity**, so each customer only ever sees their own information.

Identities live at the organization level, alongside [Data Stores](/data-stores/overview). A
data-store table can be scoped to an identity, and the agent's reads against it are automatically
filtered to the conversation's subject (and the accounts or groups that subject belongs to).

Open [**Identities**](https://www.stardeck.ai/dashboard/identities) in your Stardeck dashboard to see and manage the directory.

## Identity types

Every identity is one of three types. The type decides how it nests and whether it can be linked
to a channel.

| Type        | What it is                                   | Nests under           | Channel-linked? |
| ----------- | -------------------------------------------- | --------------------- | --------------- |
| **Account** | The root scope unit — a company or customer  | Nothing (it's a root) | No              |
| **Group**   | A collective subject, e.g. a LINE group chat | An account or group   | Yes             |
| **Person**  | An individual                                | An account or group   | Yes             |

* **Account** — the top of a tier. An account never has a parent and is never linked to a channel;
  it's the unit that holds groups and people and anchors their shared data.
* **Group** — a collective such as a LINE group or room. A group nests under an account (or another
  group) and can be linked to the channel's group/room id.
* **Person** — an individual contact. A person nests under a parent and can be linked to one or more
  channel identifiers or logins (a LINE user id, an email, a phone number, and so on).

## How scope works

Identities nest into **tiers** through *memberships*: an account holds groups, a group holds people.
Read scope flows **upward** — a subject reads its own data plus every ancestor's, and never its
members' or its siblings'.

```mermaid theme={null}
flowchart TD
  A["Account: Acme Inc."] --> G["Group: Acme support chat"]
  A --> D["Person: Dana"]
  G --> S["Person: Sam"]
```

Given the tree above:

* **Sam** reads Sam's data, the Acme support chat's data, and Acme Inc.'s data (the full path up to
  the root).
* **Dana** reads Dana's data and Acme Inc.'s data — but **not** Sam's or the support chat's.
* **Acme Inc.** reads only its own data; it has no parent.

This is what keeps one customer's conversation from reaching another's data, while still letting
everyone in a company share what belongs to the company.

<Note>
  The dashboard shows an identity's **effective read scope** — the subject plus all of its ancestors
  resolved into a flat list. That list is exactly what a scoped agent run would be able to read, so
  it's the quickest way to confirm a customer is wired up correctly before pointing an agent at it.
</Note>

## Channel links

A **channel link** ties an external identifier or login to a person or group, so inbound messages
resolve to the right subject. Accounts are never channel-linked.

| Link kind      | Typical value                       |
| -------------- | ----------------------------------- |
| LINE           | A LINE user id (person) or group id |
| Facebook       | A Facebook page-scoped user id      |
| Instagram      | An Instagram-scoped user id         |
| Email          | An email address                    |
| Phone          | A phone number                      |
| App login      | A deployed-app (project auth) user  |
| Dashboard user | A Stardeck dashboard user           |

A link can be marked **verified** when you're confident the identifier really belongs to that
subject.

<Note>
  **Inbound messages mint identities automatically.** When a message arrives on a connected channel,
  Stardeck resolves the sender to an existing identity by its channel link, or creates one on the
  spot — a **person** for a direct message (keyed to the sender's channel id) or a **group** for a
  group/room chat. You usually don't create identities by hand for live channels; you curate, link,
  and organize the ones that arrive.
</Note>

## Managing identities

### Create an identity

<Steps>
  <Step title="Open Identities">
    Go to [**Identities**](https://www.stardeck.ai/dashboard/identities) in your dashboard and click
    **New identity**.
  </Step>

  <Step title="Pick a type">Choose **Account**, **Group**, or **Person**.</Step>

  <Step title="Add details">
    Give it a display name and, optionally, an **external reference** — your own customer key, so
    you can match the identity back to a record in another system.
  </Step>

  <Step title="Optionally set a parent">
    For a group or person, you can choose the account or group it belongs to. Wiring a parent moves
    read scope, so it requires the govern permission (see [Permissions](#permissions)).
  </Step>
</Steps>

### Attach a channel link

Open an identity and add a link under **Channel links** — pick the kind (LINE, email, phone, …),
enter the external id, and mark it verified if appropriate. This is how you connect a known customer
to the channels they message you from.

### Organize memberships

An identity's **Memberships** control where it sits in the tier graph:

* **Belongs to** — the parents it reads up from. Add a parent to widen its read scope; remove one to
  narrow it.
* **Members** — the identities that belong to it.

Adding or removing a parent changes what the agent can read, so these are governed actions.

### Merge

If the same customer ends up as two identities (for example, they messaged from two channels before
you linked them), **merge** redirects one into a surviving identity of the same type. Merging moves
the loser's channel links and scope onto the survivor. It is privileged, audited, and can't be
undone automatically.

### Archive

Archiving retires an identity without deleting its history. An archived identity resolves to no read
scope, so a conversation pointed at it would read no data.

## Permissions

Identity management is controlled by two organization permissions (see
[Members & Roles](/members-and-roles)):

| Permission          | Grants                                                                       |
| ------------------- | ---------------------------------------------------------------------------- |
| `identities:manage` | View the directory, create and edit identities, and attach channel links     |
| `identities:govern` | Privileged, scope-moving actions: add/remove memberships, merge, and archive |

The split exists because anything that changes an identity's place in the tier graph changes what an
agent can read. A teammate who only holds `identities:manage` can keep the directory tidy, but can't
widen or narrow a customer's read scope.

## Using identities with AI agents

Identities come together with agents on the **AI Agents** page. Each agent has a conversation log of
the real chats it's handling. Because inbound messages mint and link identities automatically, most
conversations already carry the right subject.

When you need to correct one — an agent mis-identified a sender, or an older thread predates linking —
open the conversation and use the **Subject** selector in its header to assign or reassign the
identity. The change re-scopes the agent's data reads for that thread on its next reply. (Reassigning
is gated on `identities:manage`.)

## Keeping internal data private

Scope decides *which* customer an agent can read. It doesn't decide *what about that customer* the
agent may show. A support record often holds both: the order and its status are fine to share with
the customer; the margin, your private notes, and a churn flag are not.

Stardeck draws this line on the **data store**, not in your app's code — a scoped agent reads the
store directly, so any filtering you write in your app never runs for it. A **customer-facing agent**
(one replying to the customer) sees only the data you've marked client-facing; a **staff agent** (one
of your own team's agents, scoped to a customer to help them) sees the whole record. You separate the
two in one of two ways.

### A staff-only store

Keep internal data in its own data store and turn on **Staff-only store** in the store's General
settings. A customer-facing assistant can never be granted a staff-only store, so it can't read
anything in it — your staff agents still can. Point both stores at the same customer (the same
identity), and a staff agent reads across both while a customer-facing agent reads only the
client-facing store.

Reach for this when your internal data already lives in its own tables — private notes, risk scores,
financial detail.

### Column and row visibility on a shared store

When client and internal data share a table — the same record has a public status and a private note
— tag the sensitivity instead of splitting the table. In the store's General settings, turn on
**Enforce client/internal visibility**, then:

* **Column tiers** — mark each column **Client** or **Internal**. A customer-facing agent reads only
  the Client columns; Internal ones are hidden, and can't be searched or sorted on either.
* **Row visibility** — for each table, pick the column that decides whether a row is visible to the
  customer (for example, a "visible to client" checkbox your app already sets). A customer-facing
  agent reads only the rows where it's on. A table left **Not configured** stays hidden from
  customer-facing agents entirely.
* **Default tier** — un-tagged columns fall back to the store default. Leave it **Internal** so a new
  column stays private until you deliberately mark it Client.

<Note>
  Staff agents are never filtered — they read every column and row for the customer they're scoped
  to. Only customer-facing agents get the trimmed view, so one shared table can serve both: the
  customer sees their slice, your team sees the whole record.
</Note>

<Warning>
  Don't rely on hiding fields in your app code to keep them from a customer-facing agent — the agent
  reads the data store directly and never runs that code. Mark the data **Internal** (or move it to a
  staff-only store) so the platform enforces it.
</Warning>

## Next steps

* [Data Stores](/data-stores/overview) — scope a shared table to an identity so agents read
  per-customer data.
* [Members & Roles](/members-and-roles) — grant your team the `identities:manage` and
  `identities:govern` permissions.
* [LINE](/connected-services/line/overview) — connect a channel whose inbound messages mint and link
  identities.
