# Canic 0.9 - Auth Refactor & Delegated Certificates

**URL:** <https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053>\
**Category:** Rust\
**Created:** [January 20, 2026, 5:44pm UTC](https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053 "2026-01-20T17:44:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![borovan3](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@borovan3](https://forum.dfinity.org/u/borovan3)\
**Post date:** [January 20, 2026, 5:44pm UTC](https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053/1 "2026-01-20T17:44:35Z")

</div>

> **[GitHub - dragginzgame/canic](https://github.com/dragginzgame/canic/)**
>
> Contribute to dragginzgame/canic development by creating an account on GitHub.

# 🚀 Canic 0.9: Two Big Wins for Auth & Access Control

We’ve been heads-down on Canic’s foundations, and with **0.9** we’re excited to share two changes that materially improve how auth and access control work — both in _power_ and _clarity_.

These aren’t incremental tweaks. They unlock new capabilities while making the system easier to reason about.

* * *

## 🔐 1. A Brand-New Access Model (Finally!)

Auth in Canic is now built around a **single, expressive access expression model**.

Instead of splitting access checks across `guard`, `auth`, `env`, and `rule` stages, endpoints now declare **exactly what they require** using one `requires(...)` clause.

Access rules are written as composable expressions using explicit predicates like:

- `caller::…`

- `app::…`

- `self_env::…`

All checks are evaluated by **one async evaluator** , with deterministic short-circuiting and precise metrics.

### What that looks like in practice

```auto
#[canic_update(requires(any(
    caller::is_root(),
    all(
        caller::is_controller(),
        not(app::is_readonly()),
        custom(HasPaidAccount),
    ),
)))]
async fn update_critical_settings(
    input: SettingsInput,
) -> Result<(), canic::Error> {
    // …
}

```

At a glance, you can see:

- 🔀 how rules are combined (`any`, `all`, `not`)

- 👤 who is allowed to call it

- 📦 what app state must be true

- 🔧 where custom async logic fits in

No hidden ordering. No implicit stages. No guessing.

* * *

## 🧠 Grouping & Composition (The Part That Makes This Powerful)

Access predicates are grouped explicitly using boolean combinators:

- **`all(...)`** → every predicate must pass

- **`any(...)`** → at least one predicate must pass

- **`not(...)`** → invert a predicate or whole group

Groups can be **nested arbitrarily** , read top-down, and evaluated exactly as written. Evaluation stops on the first failure, and only that denying predicate is recorded in logs and metrics.

The result: access logic that is **local, readable, and auditable**.

## 🔑 2. Delegation You Can Actually Scale

Earlier in 0.9, we also landed a major upgrade to Canic’s delegation and trust model:

- Root is the **sole delegation authority**

- Shards store proofs locally and mint tokens without calling root

- Tokens are **verified locally** by any canister

- Issuance is explicit about certified-data requirements

- No runtime dependency on root for verification

This unlocks **high-throughput, low-latency auth** without sacrificing correctness.

 ![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/4/6/46f2ec0026c8d68adc85153dc79049375a34c8e9.jpeg)

---

<div class="post-metadata">

**Author:** ![borovan3](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@borovan3](https://forum.dfinity.org/u/borovan3)\
**Post date:** [January 20, 2026, 7:45pm UTC](https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053/2 "2026-01-20T19:45:47Z")

</div>

.. and mission 70 is literally the worst idea i’ve ever heard in my life

---

<div class="post-metadata">

**Author:** ![Phasma](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/phasma/32/27069_2.png) [@Phasma](https://forum.dfinity.org/u/Phasma)\
**Post date:** [January 20, 2026, 8:55pm UTC](https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053/3 "2026-01-20T20:55:08Z")

</div>

(post deleted by author)

---

<div class="post-metadata">

**Author:** ![borovan3](https://avatars.discourse-cdn.com/v4/letter/b/5f9b8f/32.png) [@borovan3](https://forum.dfinity.org/u/borovan3)\
**Post date:** [January 20, 2026, 9:04pm UTC](https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053/4 "2026-01-20T21:04:40Z")

</div>

Nobody ever posts on my technical stuff, that’s why I post it 🙂

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [January 21, 2026, 5:22am UTC](https://forum.dfinity.org/t/canic-0-9-auth-refactor-delegated-certificates/63053/5 "2026-01-21T05:22:38Z")

</div>

> [@borovan3](#):
>
> ```auto
> #[canic_update(requires(any(
> caller::is_root(),
> all(
> caller::is_controller(),
> not(app::is_readonly()),
> custom(HasPaidAccount),
> ),
> )))]
> async fn update_critical_settings(
> input: SettingsInput,
> ) -> Result<(), canic::Error> {
> // …
> }
> 
> ```

As someone who really enjoy the guards pattern, this looks like being really handy 👍
