Appearance
Identity Providers & Extensibility
SeyalRun can authenticate users itself, or delegate to a system that already owns your identities. Either way, SeyalRun's own authorization still applies — a delegated login says who you are, never what you may reach.
Available providers
| Provider | Source of truth | How it's enabled |
|---|---|---|
local | SeyalRun's own user table (Argon2 password + optional MFA) | Always on — the default |
zabbix_sso | Zabbix, via the frontend module | Set ZABBIX_MODULE_SECRET and install the module |
jumpserver | An existing JumpServer deployment | Set jumpserver_api_url |
Providers coexist. A provider that isn't configured returns "not me" and login falls through to the next one, so enabling delegation doesn't disable local logins for your break-glass admin.
Zabbix SSO
Users arriving from the Zabbix module never see a second login screen. The module authenticates with an HMAC secret shared with SeyalRun, SSO codes are single-use and expire after 120 seconds, and the Zabbix user type maps onto a SeyalRun role.
Zabbix permissions never widen SeyalRun access — Zabbix's host-write permission only decides whether the terminal icon is visible. Clicking it still goes through SeyalRun's own authorization gate. See Security Model.
JumpServer delegated login
For a deployment that fronts an existing JumpServer, SeyalRun can accept JumpServer's own users without giving them a second password:
POST /api/v1/auth/jumpserver-login
{"jms_token": "<the user's JumpServer access token>"}SeyalRun validates the token against JumpServer's API, reads the user's profile, auto-provisions them locally, and maps them onto a role:
| JumpServer profile | SeyalRun role |
|---|---|
is_superuser | superadmin |
| org admin, or a system role whose name contains "admin" | admin |
| everyone else | user |
The same login gates apply as any other path — IP restrictions, MFA, single session. JumpServer stays the source of truth for identity; SeyalRun remains the source of truth for access.
Configuration
| Setting | Purpose |
|---|---|
jumpserver_api_url | JumpServer's API base URL. Blank disables the provider entirely. |
jumpserver_ca_bundle | Trust root for a self-signed JumpServer |
TLS verification is never disabled
jumpserver_ca_bundle supplies a trust root — it is not a way to turn verification off. There is no setting that disables certificate verification on this path, and the plugin's test suite asserts that verify=False never appears in its source.
An auto-provisioned user gets a real role assignment row, not just a role name on the user record. Without that, RBAC would grant nothing and every request would 403 — a delegated user that can log in but can't do anything is the classic failure mode here, and it's tested against.
How plugins work
Extensibility goes through core/libs/pluginbase. Each extension point is a small abstract base class, and implementations are discovered by directory scan at startup: every module under app/plugins/<axis>/ is imported, and any class subclassing the axis base is registered under its name.
| Axis | Answers |
|---|---|
IdentityProvider | Who is this user? |
CredentialKind | What kind of secret is this (password, SSH key, vault path)? |
KeyProvider | Where does the vault's master key come from? |
CommandFilterMatcher | Does this command match this pattern set? |
ActionExecutor | How do I run this kind of job? |
TriggerSource | What external event should start a job? |
SessionBroker | Who terminates the live session and owns its transport? |
Two consequences worth understanding:
- A plugin that isn't in the image is never imported. A deployment that doesn't use an integration doesn't run — or even load — its code. That's the security property, not just tidiness.
- There is no dynamic
pip install. Plugins ship inside the image, so a built image is immutable and reproducible; you can't change behavior by dropping a file on a running host.
Related
- Access Control — roles and per-host authorizations.
- API Tokens & Scopes — programmatic identity.
