issuerd
Health Gecti
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 74 GitHub stars
Code Basarisiz
- rm -rf — Recursive force deletion command in .github/workflows/ci.yml
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Fast, Keycloak-compatible IAM with DPoP and CIBA
Fast, Keycloak-compatible IAM with DPoP and CIBA — OpenID Certified OIDC/OAuth2 in Rust, shipped as a single binary, horizontally scalable.
Proof, not promises: OpenID Certified across the 11-profile OP matrix (10 profiles on v0.1.17 + RP-Initiated Logout on v0.1.19) · 31,000+ self-hosted conformance conditions with 0 unexpected failures and 0 unexpected warnings · 100,000-user LDAP sync in ~30 s · 3,460+ automated tests · one self-contained binary.
Issuerd is a modular Identity and Access Management (IAM) server implementing OpenID Connect and OAuth 2.x. It delivers the feature surface you expect from a mature identity provider — single sign-on, MFA and passkeys, user federation, social login, a full admin console and management API — with the operational profile of a Rust service: one self-contained binary, predictable latency, and no JVM to babysit. Keycloak is used throughout as the baseline reference implementation: protocol behavior, JSON shapes, and Admin API responses are continuously validated against a real Keycloak 24.0.

Why Issuerd?
- OpenID Certified, not "spec-inspired". The OpenID Foundation registry lists Issuerd v0.1.17 for 10 OP profiles; the logout registry adds RP-Initiated Logout OP on v0.1.19. The accepted evidence comes from the OIDF-hosted conformance suite (release v5.3.3). Separately, a broader self-hosted run of release v5.3.3 passes the full OP certification matrix with zero unexpected failures and zero unexpected warnings, 31,000+ conditions verified per run, in a hermetic TLS environment against a pristine suite, with per-module results checked into the repo.
- Keycloak-compatible where it counts. Realms, clients, roles, client scopes, protocol mappers, authentication flows, and the Admin REST API follow the Keycloak model, so existing OIDC clients and Keycloak-hardened operational knowledge transfer directly. A dual-target test suite runs the same protocol assertions against Issuerd and a live Keycloak 24.0 container, and every deliberate difference is documented.
- Rust, end to end. Memory safety without a garbage collector, async I/O on Tokio, constant-time secret handling, ~155k lines of Rust across 10 tightly-scoped library crates with a strictly acyclic dependency graph. The entire server — including the embedded admin and account consoles — deploys as one binary.
- Horizontally scalable from day one. Access-token validation is stateless (no database lookup on the hot path), signing keys are shared cluster-wide through PostgreSQL, and transient coordination state lives in Redis. No sticky sessions — put any number of nodes behind any load balancer.
- Built for real directories. LDAP (Samba AD, OpenLDAP, MS Active Directory) and Kerberos/SPNEGO federation with full user and group sync — a complete 100,000-user import from a live MS AD finishes in ~30 seconds (~3,300 users/s). Password validation via bind, password write-through, and group-membership reconciliation included.
- Batteries included. Embedded React admin console and end-user account console served same-origin, themable login pages, per-realm i18n with localized emails, declarative YAML provisioning, one-command OpenAPI export, Prometheus metrics, health/readiness probes, TLS.
- Engineered for testability. 3,460+ automated tests; every public function is testable without network or database; authentication state transitions are proven at compile time via typestate markers. The discovery document advertises exactly what is implemented and tested — nothing more.
Built for the Agent Era
AI agents acting on behalf of your users break the assumptions bearer tokens were designed around: an agent holds credentials for hours, calls many downstream services, and reads untrusted input all day. Prompt-injection is not a thought experiment — it is Tuesday. Issuerd already ships the three standards the industry has converged on for exactly this world. Not on the roadmap — implemented, test-covered, and recorded live:
- Tokens that are worthless when stolen (RFC 9449 DPoP). Every access token can be cryptographically bound to its holder's key via the
cnf.jktconfirmation claim. Proofs are method- and URL-bound, short-lived, and single-use through a distributedjtireplay cache. A token lifted from a log, a proxy, or a compromised MCP server is scrap metal: presenting it without the matching private key is a401 invalid_dpop_proof. - Agents that never forward their login token (RFC 8693 token exchange). Each tool call mints a fresh, audience-narrowed, scope-attenuated token on the spot: a
get_orderscall travels withaud = mcp-serverandscope = orders:read— nothing more. Scope can only ever shrink across an exchange (asking for more isinvalid_scope), targets opt in explicitly, and the DPoP binding survives the exchange. - Humans in the loop for the dangerous actions (CIBA, poll mode). Privileged scopes like
refunds:executeexist nowhere in an agent's standing credentials. When an action crosses the agent's autonomy limit, Issuerd interrupts the user with an explicit approval request carrying a binding message — "Refund $150 for order #123" — and only an approval mints a short-lived, DPoP-bound step-up token. A denial isaccess_denied; without a human yes, that authority simply never exists.
Both scenarios below ran end-to-end against a live Issuerd rig — a scripted chat agent calling a real MCP server backed by PostgreSQL row-level security. The attacks are real too: prompt injection absorbed by row-level security, a stolen token replayed with bare curl, and a refund attempted without step-up. What you see is what the servers actually answered.
| MCP scenario — attenuated, sender-constrained tool calls | CIBA scenario — human step-up approval |
|---|---|
![]() |
![]() |
Login → exchange down to aud = mcp-server, orders:read → orders listed → injection changes nothing → replayed token: 401 |
Refund requested → approval card with binding message → short-lived step-up token → refund applied → same call without it: 403 |
Guides with the full protocol detail, curl walkthroughs, and the failure matrix: Agentic IAM: MCP tool calls with DPoP and token exchange and Human step-up approval for agent actions: CIBA.
Built-in MCP administration with exact-operation approval
Issuerd itself also exposes a realm-scoped MCP server with 71 curated administration/self-service tools and three redacted resources. Any hosted or local LLM can participate through a compatible MCP client; server-side policy, not the prompt, defines the boundary. Reads and reversible writes stay within explicit scopes and realm roles. Strict operations require fresh human approval for canonical tool + arguments and expected state, followed by a single-purpose DPoP token without refresh. Changed arguments fail, and exact retries return the recorded result without a second mutation. See the MCP server guide, the exact-operation security article, and the official-SDK acceptance example.
Issuerd vs. Keycloak
Issuerd deliberately mirrors Keycloak's domain model and API surface — it is not a from-scratch reinvention of IAM concepts. The difference is in the implementation and operations:
| Issuerd | Keycloak | |
|---|---|---|
| Runtime | Single Rust binary | JVM (Quarkus) distribution |
| Cluster state | PostgreSQL + Redis | Embedded Infinispan grid |
| Protocol parity | Continuously diff-tested against Keycloak 24.0 | Reference |
| Conformance evidence | OpenID Certified (11 OP profiles across v0.1.17/v0.1.19); public OIDF listings and per-release report bundles | Vendor certification program |
| SAML, UMA, FGAP, Organizations | Not implemented (see scope) | Implemented |
If your clients speak standard OIDC/OAuth2 and your team knows Keycloak's model, Issuerd is a drop-in alternative with a Rust operational footprint.
Feature Overview
Protocols & grants
- OpenID Connect Core: authorization code flow with PKCE (S256-only), implicit/hybrid response types, all response modes (
query,fragment,form_post, and the JARM*jwtfamily) - OAuth2 grants:
password,client_credentials(service accounts), refresh token rotation with reuse detection, device authorization (RFC 8628), CIBA (poll mode) - Advanced OAuth: PAR (RFC 9126), JAR (RFC 9101), JARM, RAR
authorization_details(RFC 9396), token exchange & impersonation (RFC 8693), DPoP sender-constraining (RFC 9449), dynamic client registration (RFC 7591/7592), pairwise subjects (OIDC Core §8) - Client authentication:
client_secret_basic/post,private_key_jwt,client_secret_jwt - Offline tokens, per-realm signing algorithm selection (RS256/384/512, ES256/384/512, EdDSA), key rotation
- Session management: logout with
id_token_hint, backchannel + frontchannel logout, realmnot_beforerevocation
Identity
- MFA: TOTP (RFC 6238) and WebAuthn/passkeys as second factors, required-action enrollment
- Passwordless email-code login (per-realm opt-in)
- Identity brokering: external OIDC + social IdPs (Google/GitHub/Microsoft presets), first-broker-login, account linking, IdP mappers
- User federation: LDAP (Samba AD, OpenLDAP, MS AD) and Kerberos/SPNEGO, full user + group sync, password validation via bind, password write-through
- Self-service: registration, forgot/reset password, remember-me, account console (profile, credentials, TOTP, passkeys, consents, linked accounts, sessions)
- Brute-force protection, password policies with history, attack-detection endpoints
Administration
- Reference-compatible REST Admin API with OpenAPI 3.0 export and an embedded React admin SPA
- Client scopes & protocol mappers (claim shaping into tokens), client roles, composite roles
- Editable authentication flows, required actions, events & admin-event auditing
- Partial import/export, key rotation/disable, client adapter-config download
- Declarative realm provisioning from YAML at first startup
End-user experience
- Themable login pages, per-realm locales, localized SMTP email templates
- Embedded account console with dark/light themes
Platform
- Horizontal scaling: stateless token validation, shared signing keys, no sticky sessions (PostgreSQL + Redis)
- Standalone daemon binary with TLS, Prometheus metrics,
/healthand/readyprobes, graceful shutdown - Official Dockerfile plus compose stacks for a full integration environment and a two-node cluster demo
Standards Coverage
| Specification | Status |
|---|---|
| OpenID Connect Core 1.0 | OpenID Certified on v0.1.17 (Basic, Implicit, Hybrid, Config, Dynamic, Form Post, 3rd-Party-Init OP) |
| OpenID Connect Discovery | Full metadata, truthful capability advertisement |
| OIDC RP-Initiated, Front-Channel & Back-Channel Logout | OpenID Certified: RP-Initiated on v0.1.19; Front-Channel & Back-Channel on v0.1.17 |
| OIDC Session Management 1.0 | OpenID Certified on v0.1.17 (Session Management OP) |
| OAuth 2.0 (RFC 6749) + Bearer Tokens (RFC 6750) | Implemented |
| PKCE (RFC 7636) | S256-only, enforced for public clients |
| Token Introspection (RFC 7662) | Implemented |
| Device Authorization Grant (RFC 8628) | Implemented |
| Token Exchange (RFC 8693) | Implemented, incl. impersonation |
| Resource Indicators (RFC 8707) | Implemented; exact-allowlist, gated by [mcp] enabled (default off) |
| Pushed Authorization Requests (RFC 9126) | Implemented |
| JWT-Secured Authorization Requests — JAR (RFC 9101) | Implemented |
| JWT-Secured Authorization Response Mode — JARM | Implemented |
| Rich Authorization Requests (RFC 9396) | Implemented |
| DPoP (RFC 9449) | Implemented (mTLS sender-constraining deferred) |
| OAuth 2.0 Protected Resource Metadata (RFC 9728) | Implemented; gated by [mcp] enabled (default off) |
| Model Context Protocol (2025-06-18, 2025-11-25, 2026-07-28) | Implemented; realm-scoped server with 71 tools and 3 resources, disabled by default |
| Dynamic Client Registration (RFC 7591/7592) | Implemented, incl. read/update/delete |
| CIBA (OpenID Connect Client-Initiated Backchannel Authentication) | Poll mode |
| TOTP (RFC 6238), WebAuthn / FIDO2 | Implemented |
| JWT / JWS / JWK (RFC 7515–7519) | RS/ES family + EdDSA, per-realm algorithm selection |
OIDC Conformance
Issuerd is listed in the official OpenID Foundation certification registries:
| Certified version | Certified OP profiles | Official registry |
|---|---|---|
| v0.1.17 | Config, Basic, Implicit, Hybrid, Dynamic, 3rd Party-Init, Form Post, Front-Channel Logout, Back-Channel Logout, Session Management | OIDC implementations · Logout profiles |
| v0.1.19 | RP-Initiated Logout | Logout profiles |
These registry entries are version-specific: they do not mean that v0.1.19 alone is certified for all 11 profiles.
Across the two accepted certification submissions, the OIDF-hosted runs used the OpenID Foundation Conformance Suite (release v5.3.3): 33 plan invocations, 524 modules FINISHED — 393 PASSED, 41 declared SKIPPED, 90 REVIEW with screenshots — with no FAILED or INTERRUPTED results.
The broader self-hosted engineering matrix below used release v5.3.3 in a hermetic TLS environment against a pristine, unpatched suite: 43 plan invocations, 612 test modules, 31,000+ conditions, 0 unexpected failures and 0 unexpected warnings:
| Self-hosted profile | Result |
|---|---|
| Config OP | PASSED |
| Basic OP | PASSED |
| Implicit OP | PASSED (id_token, id_token token) |
| Hybrid OP | PASSED (all three hybrid types) |
| Dynamic OP | PASSED — 6 response types × DCR (RFC 7591/7592), per-client signing algs, signed userinfo, JAR-by-reference |
| Form Post OP | PASSED (basic / implicit / hybrid legs) |
| 3rd Party-Init OP | PASSED (×6) |
| RP-Initiated Logout OP | PASSED (×6) |
| Session Management OP | PASSED (×6) — session_state + check_session_iframe |
| Front-Channel Logout OP | PASSED (×6) |
| Back-Channel Logout OP | PASSED (×6) — signed logout tokens |
oidcc-server-rotate-keys is the one manual-step module the pristine runner cannot exercise in-plan (upstream's own CI lists it identically) — the harness produces real evidence instead: tests/conformance/run-rotation-check.sh drives it standalone with a live admin-API key rotation (PASSED on every full run).
Setup and per-module results: tests/conformance/README.md, tests/conformance/COVERAGE.md; logs are written to the (gitignored) tests/conformance/results/ directory when the suite runs.
Every GitHub Release re-runs the suite — together with the rest of the heavy test suites — against the exact tagged commit and attaches the complete report bundle as a standalone release asset: issuerd_<version>_conformance-evidence.tar.gz, containing the HTML reports, JSON exports, and runner logs, covered by SHA256SUMS.txt and a build-provenance attestation.
# Re-run the full conformance suite (requires Docker)
git clone https://gitlab.com/openid/conformance-suite.git tests/conformance/conformance-suite # once
cd tests/conformance && docker compose up # or ./run.sh (CI: exit code + teardown)
Quickstart
Option A — Docker (one command, everything included)
docker compose up
This pulls the published image (issuerd/issuerd:latest) and starts a single-node Issuerd with PostgreSQL and Redis on http://localhost:8080, seeded on first start with the master realm (admin admin / admin) and a demo realm myrealm (user alice / changeme, sample clients my-app and public-app). No build tools required — only Docker. Pin a specific release with issuerd/issuerd:<version> in docker-compose.yml; to build from local sources instead, use docker compose -f docker-compose.yml -f docker-compose.from-source.yml up --build.
Prebuilt binaries (Linux/Windows, with SBOM and checksums) are attached to each GitHub Release.
- Admin console: http://localhost:8080/admin/console
- Account console: http://localhost:8080/realms/myrealm/account
- Discovery: http://localhost:8080/realms/myrealm/.well-known/openid-configuration
Stop with docker compose down; wipe the demo data with docker compose down -v.
Option B — local Rust build
Prerequisites: a Rust toolchain (1.95+) and — for the embedded web consoles — Node.js 20+.
# 1. Build the embedded web client (admin console, account console, login pages)
cd webclientsrc && npm ci && npm run build && cd ..
# 2. Run the server — zero external dependencies (in-memory backend)
cargo run --bin issuerd -- daemon
The server listens on http://localhost:8080 and seeds the same demo content via the checked-in issuerd.toml.
Skipping step 1 still yields a fully functional OIDC/OAuth2 and Admin REST API server; only the browser consoles and login pages stay unembedded.
Useful companion commands:
# Export the OpenAPI specification
cargo run --bin issuerd -- openapi -o openapi.json
# Generate fully-commented example configs
cargo run --bin issuerd -- example server-config -o my-server.toml
cargo run --bin issuerd -- example provision-config -o my-provision.yaml
More deployment options
# Contributor integration stack: extra PostgreSQL, Redis, reference Keycloak,
# Bind9, Samba AD DC, OpenLDAP (used by the dual-target and federation tests)
docker compose -f docker-compose.integration.yml up -d
# Two Issuerd nodes behind an nginx load balancer (PostgreSQL + Redis)
docker compose -f docker-compose.cluster.yml up -d --build
# LB endpoint: http://localhost:8088 — see docs/CLUSTERING.md
Architecture at a Glance
A Cargo workspace of 9 library crates plus the issuerd binary. The dependency graph is a strict DAG: only issuerd-core is a universal dependency, and issuerd-server is the composition root that wires everything together.
| Crate | Responsibility |
|---|---|
issuerd-core |
Shared types, traits, errors, ID types, models — no I/O, no async |
issuerd-protocol |
OIDC/OAuth2 request parsing & validation — pure functions |
issuerd-auth-flow |
Pluggable authentication flow engine, TOTP, WebAuthn, email codes |
issuerd-token |
JWT/JWS/JWK issuance, signing, validation, introspection |
issuerd-storage |
Storage trait + PostgreSQL (sqlx), in-memory, and JSON-file backends |
issuerd-federation |
User federation SPI: LDAP, Kerberos/SPNEGO, user sync |
issuerd-admin-api |
REST Admin API (Axum + utoipa/OpenAPI) |
issuerd-cluster |
Distributed cache (Redis cluster) & node discovery |
issuerd-server |
Composition root: HTTP bootstrap, middleware, TLS, metrics |
Design contracts (stateless validation, testability rule, typestate auth boundaries, horizontal scaling): see ARCHITECTURE.md.
Testing & Quality
3,460+ automated tests. Unit tests live next to the code; every public function is testable without network I/O or database via trait-based fakes (
InMemoryStorage,InMemoryCache, mock crypto).cargo test --workspace --lib # unit tests, fast, no I/O cargo test --workspace # + in-process E2E suite (< 30 s, no Docker)Dual-target protocol parity. A subset of the E2E suite runs the same assertions against Issuerd and a real Keycloak 24.0 container (
ISSUERD_TEST_TARGET=keycloak|both) to catch behavioral drift.Real-directory federation tests against Samba AD DC, OpenLDAP, and Windows Server AD (skip gracefully when unavailable), plus large-scale sync load tests (100k users). A full 100,000-user sync from a live MS AD lab completes in ~30 s (~3,300 users/s on the
rig/lab stack with PostgreSQL).CI-enforced hygiene:
cargo clippy --workspace --all-targets --all-features -- -D warningsandcargo fmt --checkmust stay green.Fast coverage with
cargo-llvm-cov:cargo llvm-cov --workspace --lib --summary-only
Documentation
The full documentation set is also published at issuerd.org — rendered, searchable, with the same content as the files below.
| File | Purpose |
|---|---|
| docs/README.md | Operations documentation set — installation, configuration, provisioning, deployment, administration, federation, security, monitoring, backup/upgrade, troubleshooting |
| webclientsrc/openapi.json | Issuerd API — OpenAPI spec covering the Admin REST API plus the account-console, public protocol, and internal SPA endpoints |
| CHANGELOG.md | Project changelog and release history |
| ARCHITECTURE.md | High-level design + module contracts |
| AGENTS.md | Conventions, build/test commands, per-crate notes, compatibility policy |
| docs/CLUSTERING.md | Multi-node deployment guide |
| docs/PERFORMANCE.md | Measured performance & sizing vs Keycloak 26.7 (k6 benchmark stack) |
| docs/mcp-server.md | Built-in MCP server — 71 curated tools, three resources, DPoP, same-realm authorization, and exact-operation CIBA |
| docs/mcp-exact-operation-approval.md | Agent-native security architecture — one fresh approval for one exact operation, atomic execution, and replay reconciliation |
| docs/agentic-iam-mcp.md | External agentic IAM — downstream MCP tool calls secured with DPoP + RFC 8693 token exchange (demo GIF included) |
| docs/ciba-step-up.md | Human step-up for agents — scope-based and exact-operation CIBA approval flows |
| docs/openid-conformance.md | OIDC conformance and certification — self-hosted evidence, hosted submissions, the 11-profile version matrix, and resubmission lessons |
| tests/KEYCLOAK_DIFFS.md | Documented divergences from Keycloak behavior |
| tests/conformance/README.md | OIDC conformance suite harness & results |
Stability & Compatibility
Backward compatibility is a standing commitment across numbered releases:
- Database — the schema evolves exclusively through new, append-only migrations. Existing migration files are never modified, and upgrading from any earlier schema version happens automatically at startup.
- APIs — the Admin REST API and the OIDC/OAuth2 protocol surface change additively. Breaking changes require an explicit deprecation window, a documented migration path, and a
CHANGELOG.mdentry. - Configuration & provisioning — new config keys and provision-YAML fields are optional with sensible defaults, so existing deployments keep booting unchanged.
The contributor-facing policy is enforced through AGENTS.md.
Project Scope
All OIDC-parity feature areas are implemented. Deliberately out of scope for now: SAML 2.0, fine-grained admin permissions (FGAP), UMA/Authorization Services, Organizations, FAPI 2.0 message signing, CIBA ping/push modes.
Contributing
See CONTRIBUTING.md for the development workflow, the CI gates, and the standing rules (backward compatibility, truthful discovery, dynamic admin SPA). The deep engineering conventions live in AGENTS.md; participation is governed by the Code of Conduct.
Security
If you discover a security vulnerability in Issuerd, please report it privately — see SECURITY.md for the reporting process, scope, and supported versions.
License
Copyright 2026 Dmitry Andreev [email protected] and contributors.
Apache-2.0 — see LICENSE and NOTICE.
Trademark
"Issuerd" and the Issuerd logo are unregistered trademarks claimed by the project. The code is Apache-2.0-licensed; the name and logo are not. See TRADEMARK.md.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi

