Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

15 changes: 13 additions & 2 deletions docs/concepts/canisters.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ For a deeper dive, see [Orthogonal persistence](orthogonal-persistence.md).

## Canister IDs and principals

Every canister gets a globally unique **canister ID** when it is created. This ID is a [principal](https://learn.internetcomputer.org/hc/en-us/articles/34250491785108): the same type of identifier used for users: and serves as the canister's address on the network.
Every canister gets a globally unique **canister ID** when it is created. This ID is a [principal](principals.md): the same type of identifier used for users, and serves as the canister's address on the network.

To send a message to a canister, you include its canister ID in the message header. The network routes the message to the correct subnet and places it in the canister's input queue for processing.

Expand Down Expand Up @@ -114,11 +114,22 @@ Under the hood, each canister maintains several components:
- **Controllers list**: the set of principals authorized to manage the canister.
- **Settings**: configurable parameters like compute allocation, memory allocation, and the freezing threshold (the cycles balance below which the canister stops accepting new messages to avoid running out).

## Inter-canister messaging and error handling

Canisters communicate by sending **requests** to other canisters and registering a **callback** to be invoked when the callee sends a response. The network guarantees that every request receives a reply: if a callee becomes unreachable or explicitly rejects a call, the Internet Computer synthesizes a reject response and delivers it to the caller's callback. Callbacks are never dropped.

This bidirectional request/reply model is one way canisters differ from pure actors in classical actor-based systems, which typically use one-way fire-and-forget messages.

**Trap behavior with outgoing calls:** When a canister processes a message, it may send outgoing requests before completing. Each time a canister sends a request, the network records a commit point. If the canister later traps while awaiting a response, its state reverts to what it was immediately after that last outgoing request was dispatched, not to the beginning of the original incoming message. This means any state changes made after the last outgoing call are rolled back, while changes made before it are preserved.

This has a practical implication: if a canister modifies state and then makes an inter-canister call in the same message, it must account for the possibility that subsequent code (including the callback handler) will see the state as it was when the call was sent.

## Next steps

- [Cycles](cycles.md): how canisters pay for computation
- [Principals](principals.md): the identity model and canister controllers
- [App architecture](app-architecture.md): how canisters fit into application design
- [Canister lifecycle](../guides/canister-management/lifecycle.md): practical guide to managing canisters
- [Network overview](network-overview.md): the infrastructure canisters run on

<!-- Upstream: informed by dfinity/portal docs/building-apps/essentials/canisters.mdx, message-execution.mdx -->
<!-- Upstream: informed by dfinity/portal docs/building-apps/essentials/canisters.mdx, message-execution.mdx; informed by Learn Hub articles "Canister Smart Contracts", "Computational Model" (migrated, source retired) -->
1 change: 1 addition & 0 deletions docs/concepts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Understand the ideas behind the Internet Computer before you build on it. These
- **[Network Overview](network-overview.md)**: Subnets, nodes, consensus, and boundary nodes.
- **[Application Architecture](app-architecture.md)**: How ICP applications are structured: canisters, frontends, and inter-canister communication.
- **[Canisters](canisters.md)**: Programs that run WebAssembly, hold state, serve HTTP, and pay for their own compute.
- **[Principals](principals.md)**: The identity model: users, canisters, anonymous calls, and canister control.

## Core capabilities

Expand Down
72 changes: 72 additions & 0 deletions docs/concepts/principals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
title: "Principals"
description: "What principals are on ICP: the identity model, principal classes, canister control, and how authentication works"
---

A **principal** is any entity that can authenticate with the Internet Computer and be identified when calling a canister. Principals are the building block of identity and access control on ICP: canisters use them to identify callers, enforce permissions, and determine which entities have control over which resources.

## Principal classes

There are four classes of principals on ICP:

**1. Management canister principal (`aaaaa-aa`):** The IC management canister is a virtual system API that canisters call to perform operations like creating other canisters or changing settings. It does not run at a real canister address; it uses the fixed principal `aaaaa-aa`. Canisters call it with `ic_cdk::management_canister::*` (Rust) or via actor references in Motoko.

**2. Canister IDs:** Each canister on ICP has a unique principal derived when the canister is created. Canister principals look like `ryjl3-tyaaa-aaaaa-aaaba-cai`. When a canister makes a call to another canister, the callee sees the calling canister's canister ID as the caller principal.

**3. Self-authenticating IDs:** User identities are derived from public keys using a domain-separated hash. Anyone holding the corresponding private key can authenticate and call canisters under that principal. Self-authenticating principals look like `o2ivq-5dsbb-hhfso-w2o5v-7qiaq-g4fbm-6qhhb-xbj6w-szpxa-lflfa-mae` for Ed25519 keys or similar for ECDSA keys. The [Internet Identity](https://identity.ic0.app/) service manages key-backed identities for end users.

**4. Anonymous principal (`2vxsx-fae`):** Messages that are not signed use the anonymous principal as their caller identity. Any canister can check whether a caller is anonymous and decide how to handle unsigned requests (for example, allowing public reads but rejecting state changes from anonymous callers).

A fifth class, **derived IDs**, was reserved in the specification but has never been implemented.

## How principals are used in practice

When a user calls a canister, the Internet Computer authenticates the user's signature and passes the corresponding principal as the `caller` to the canister's message handler. Canisters can then make authorization decisions based on the caller:

```
Caller is user → self-authenticating principal (derived from their public key)
Caller is another canister → that canister's canister ID
Unsigned request → 2vxsx-fae (anonymous principal)
```

This means that from a canister's perspective, all callers are principals. There is no separate "user object" or session token: the principal is the identity.

## Canister control

Canisters are managed by their **controllers**: a list of principals (users, other canisters, or DAOs) that have permission to perform management operations on the canister. Controllers can:

- Upgrade the canister's Wasm module.
- Change canister settings (compute allocation, memory allocation, freezing threshold).
- Start or stop the canister.
- Delete the canister and claim its remaining cycles.
- Add or remove other controllers.

The control structure can take several forms:

| Control structure | Who is the controller | Effect |
|---|---|---|
| Centralized | A single developer's principal | Full developer control; standard for development |
| Multi-signature | A multi-signer wallet like [Orbit](https://orbitwallet.io/) | Requires multiple keys to approve changes |
| DAO-governed | An SNS governance canister | Upgrades require a governance proposal |
| No controller | Empty controller list | Immutable canister; code can never be changed |

When a canister has no controllers, it is **immutable**: no one can modify its code or settings. Users who want to trust that a canister's behavior will never change can verify this on the [ICP Dashboard](https://dashboard.internetcomputer.org).

## Canister upgrades and stable memory

When a controller upgrades a canister, the new Wasm module replaces the old one. By default, Wasm heap memory is cleared on upgrade because the new module may have a different memory layout. However, **stable memory is always preserved** across upgrades: it is explicitly managed by the canister (via system API calls) and designed to survive code changes.

The runtime runs upgrade hooks atomically around the code swap:
1. `pre_upgrade` (or `system func preupgrade` in Motoko): save any heap data to stable memory.
2. New Wasm module is installed.
3. `post_upgrade` (or `system func postupgrade`): read data back from stable memory into the new heap layout.

If the `pre_upgrade` hook traps, the upgrade is aborted and the canister continues running the old code. If `post_upgrade` traps, the new code is installed but the canister is left in a failed state.

## Next steps

- [Canisters](canisters.md): how canisters work, lifecycle, and message types
- [Authentication](../guides/authentication/internet-identity.md): integrating Internet Identity and other authentication providers
- [IC Interface Specification: Principals](../references/ic-interface-spec/index.md#principal): the formal specification

<!-- Upstream: informed by Learn Hub articles "What is a Principal?", "Canister Control" (migrated, source retired) -->
6 changes: 1 addition & 5 deletions docs/references/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -502,11 +502,7 @@ builds upon this functionality.

#### principal

A **principal** is an entity that can be authenticated by the [Internet Computer](#internet-computer-protocol-icp). This is the same sense of the
word principal as the [Wikipedia
definition](https://en.wikipedia.org/wiki/Principal-(computer-security)).
Principals that interact with the Internet Computer do so using a
certain [identity](#identity).
A **principal** is an entity that can be authenticated by the [Internet Computer](#internet-computer-protocol-icp). Principals include canister IDs, user identities derived from public keys, and the anonymous principal. See [Principals](../concepts/principals.md) for the full classification and how they are used for access control.

#### proposal

Expand Down
Loading