auth Plugin
A detailed guide to the auth built-in plugin, including its authorization flow, role resolution model, available actions, and how it uses guard, effect, and resolve points
auth Plugin
auth is the most platform-rule-oriented built-in plugin in Downcity today.
It is not mainly there to add a user-facing business feature. It answers three foundation questions:
- who is allowed to enter the chat pipeline
- which users and chats has the platform already observed
- what is the effective role of one user right now
What it does
auth is responsible for four main jobs:
- check authorization on inbound chat traffic
- record observed users and chat principals
- resolve a user's effective role in one channel
- expose authorization config and snapshots through actions
So it spans:
- entry guarding
- runtime observation
- permission resolution
- control-plane actions
Why it is a special plugin
Unlike most other built-in plugins, auth is not treated like a normal optional plugin.
Its availability semantics are currently:
enabled: trueavailable: true
In practice, it is always treated as usable.
That design makes sense because once authorization becomes a fully optional capability that can disappear like any other utility plugin, the platform rule layer becomes unstable.
Which plugin capabilities it uses
auth uses:
availabilityhooks.guardhooks.effectresolvesactions
It does not use:
setupusagesystemhttp.runtime
That tells you auth is not a UI-installable dependency plugin, and it is not mainly driven by prompt injection.
Typical runtime flow
When a normal chat message enters the system, auth usually participates in this order:
- the chat inbound flow reaches an authorization point
- the
guardhook evaluates the incoming channel, chatId, userId, and related fields - if authorization fails, the pipeline stops immediately
- if authorization passes, the rest of the message flow continues
- a later observation point uses
effectto record observed user or chat data - whenever downstream logic needs the user's role, it calls the
resolvepoint
In short:
guarddecides whether the message can entereffectrecords what was observedresolveanswers the role question
Typical scenarios
Scenario 1: only allow specific Telegram users to talk to the agent
You can write authorization rules into auth, and every inbound Telegram message will pass through the guard check first.
If a user is not allowed, the message never reaches the later agent execution stages.
Scenario 2: after connecting one group chat, you want to inspect what principals the system has already seen
Call the snapshot action and inspect:
- recorded users
- recorded chats
- the currently effective authorization config
Scenario 3: downstream capability policy depends on user roles
For example:
- admins may use high-risk tools
- regular members may only run read-only tasks
In that case, downstream logic can use the resolve point instead of duplicating authorization-store reads.
How to register it in the SDK
import { Agent, authPlugin } from "@downcity/agent";
const agent = new Agent({
id: "chat-agent",
path: "/path/to/project",
tools: {},
plugins: [authPlugin],
});auth is more often consumed automatically by runtime integration points than manually called like a business plugin.
Main actions
auth exposes four core actions.
| Action | What it does | Best use case |
|---|---|---|
snapshot | read the current authorization snapshot | inspect observed state and rules |
readConfig | read the authorization config | control-plane UI or debugging |
writeConfig | write authorization config | bulk update policy rules |
setUserRole | set one user's role | change role assignment for one user |
Read the current authorization snapshot
const snapshot = await agent.plugins.runAction({
plugin: "auth",
action: "snapshot",
});This usually returns:
- current authorization config
- recorded users
- recorded chats
Read the current authorization config
const config = await agent.plugins.runAction({
plugin: "auth",
action: "readConfig",
});Write a new authorization config
const result = await agent.plugins.runAction({
plugin: "auth",
action: "writeConfig",
payload: {
config: {
telegram: {
enabled: true,
},
},
},
});Set the role for one user
const result = await agent.plugins.runAction({
plugin: "auth",
action: "setUserRole",
payload: {
channel: "telegram",
userId: "123456",
roleId: "admin",
},
});How it relates to hooks and resolve
auth is one of the clearest built-in examples for understanding these mechanisms:
guard: stop messages that should not entereffect: record observed principalsresolve: return the effective user role
If those concepts still feel abstract after reading this page, continue with:
Its boundary relative to services
auth is not a long-lived connection-holding or worker-like service.
It is closer to a rule orchestration layer:
- attach rules at important runtime points
- expose config and state through one standard boundary
- let other capabilities read resolved roles through a common interface
If you think of it as a service first, it becomes easy to over-couple permission checks to one long-lived runtime instance. The current design intentionally avoids that.
Important boundaries
It focuses on chat authorization and role resolution
auth is not a general-purpose ACL system or a universal resource authorization framework.
Its current focus is the chat-channel domain.
It depends on standard channel identifiers
Current channel handling expects standard values such as:
telegramfeishuqq
If the channel is invalid, the relevant action or hook will fail fast.
It is not a setup-oriented plugin
You do not use setup or usage for model installation or provider switching the way you do with web, asr, or tts.
Its value is rule evaluation, not dependency installation.
When to study it first
Use auth as a reference when you want to design:
- inbound guards
- principal observation
- role resolution
- platform-rule plugins
Related docs
Built-in Plugin Overview
A structured guide to the six built-in plugins in Downcity, what each one is for, how they differ, and which runtime shape each plugin represents
skill Plugin
A detailed guide to the skill built-in plugin, how it handles skill discovery, installation, lookup, and system injection, and why the best workflow is find, install, then lookup