ErtisAuth
Open source · MIT · .NET 10

Identity and Access Management

The right identity, the right access, stronger security_

ErtisAuth, delivers centralized, scalable, and secure identity and access management across your entire application ecosystem. From web and native applications to mobile apps and APIs, manage authentication, authorization, tokens, memberships, roles, granular & flexible permissions, dynamic user type management and OAuth integrations from a single platform.

Lightweight

One service, one database. No JVM, no separate admin server, no SQL migrations.

API first

Memberships, users, roles, providers and hooks are managed through the same REST API that issues the tokens.

Multi-tenant

Each membership operates as a fully isolated environment, allowing you to securely manage multiple channels and product ecosystems under a single service—without compromising separation or security.

Free and open

MIT licensed. No per-user pricing, no feature tiers, your data stays in your database.

Features

Everything an identity service needs

From the first sign-in to webhooks on every event, ErtisAuth covers the whole account lifecycle.

Tokens and sessions

JWT bearer tokens for users and Basic tokens for applications, refresh tokens that are single-use by default, revocation per session or for all devices, and scoped tokens limited to a subset of permissions.

bearer
JWT
basic
app_id:secret
refresh
single-use
scoped
users.read
generate-tokenrefresh-tokenrevoke-token

Memberships

Isolated tenants, each with its own users, roles, applications, secret key, token lifetimes and mail settings.

RBAC and UBAC

Roles with permissions and forbidden rules, plus per-user and per-application overrides. The same model protects your own APIs.

External providers

Sign in with Google, Apple (web and native), Facebook and Microsoft. Provider tokens are validated on the server, never trusted from the client.

Google
Google
Facebook
Facebook
Facebook (limited)
Facebook (limited)
Apple
Apple
Apple (native)
Apple (native)
Microsoft
Microsoft

Dynamic user types

Define custom user fields with a JSON schema at runtime: validation, default values, unique fields and inheritance, without changing code.

Device sign-in

A code flow for smart TVs, kiosks and CLI tools: the device shows a short code, a signed-in user approves it, the device gets a token.

K7QF-X2MP
Signed in
K7QF-X2MPApprove
Approved

Account lifecycle

Email activation, password reset with single-use tokens, one-time passwords, and freezing an account to revoke all of its tokens at once.

Modern password hashing

Argon2id and PBKDF2, chosen per membership. Legacy algorithms are still supported, so existing user databases can be imported.

Supported algorithms;
MD5
SHA1
SHA2_224
SHA2_256
SHA2_384
SHA2_512
SHA2_512_224
SHA2_512_256
SHA3_224
SHA3_256
SHA3_384
SHA3_512
ARGON2ID
PBKDF2_SHA256
PBKDF2_SHA512

Events and hooks

Every operation is recorded as an event. Webhooks call your endpoints from a background queue, and mail hooks send templated emails.

TokenGenerated→webhook200
UserCreated→mail hooksent
UserCreated→webhook200

Ready for production

OpenAPI reference with Scalar, Prometheus metrics, Application Insights, health checks and a Docker image that runs as a non-root user.

Permission model

Four segments, any resource

A permission is an expression that names who may do what on which resource. Wildcards and shorter forms keep roles short, and the same expressions protect your own services.

*.orders.read.{id}
subject
Who performs the action: a user or application id
resource
The type of resource, e.g. users or orders
action
create, read, update, delete or a custom action
object
The id of a single resource

How a request is decided

  1. 1

    A matching user or application permission decides first, whether it grants or forbids.

  2. 2

    Otherwise the role decides, and a forbidden rule of the role always wins.

  3. 3

    Users may still read and update their own record, unless the role forbids it.

  4. 4

    A scoped token must also cover the request with its scopes.

Example requests

Request

GET users/42

User: u-7 · Role: editor

Required permission

u-7.users.read.42

User permissions (u-7)

  • +*.orders.read.*

Role permissions (editor)

  • +*.users.read.*
  • +*.roles.read.*
  • +*.users.update.*
  • −*.users.delete.*
…

Security

Secure defaults, built in

An identity service is only as safe as its defaults. These protections are part of ErtisAuth and on from the start, with nothing to switch on.

Authentication

  • Argon2id or PBKDF2 password hashing, chosen per membership
  • Provider tokens are checked with the provider on the server, and an unverified email never links an existing account
  • Refresh tokens are single-use by default
  • Changing a password signs the user out on every other device

Isolation

  • A token of one membership is rejected by every other membership
  • Users and applications without a role are denied, never allowed by default
  • Scoped tokens can't reach beyond their scopes
  • Each membership signs its tokens with its own secret key of at least 32 bytes
  • All queries run solely within an isolated space specific to their own membership.

Data and queries

  • Queries can't run server-side JavaScript ($where, $function)
  • Password hashes and secrets can't be read, filtered or sorted on
  • Unexpected errors return a generic message; the details stay in the logs
  • Event records and webhooks don't carry tokens or secrets

Codes and secrets

  • One-time passwords and device codes come from a cryptographically secure generator
  • One-time passwords are single-use and limited in attempts
  • Device sign-in keeps the polling secret apart from the code the user types, and stores it hashed
  • Each application has its own secret, which can be rotated

Your part

TLS, rate limiting on public endpoints and network access to MongoDB belong to your gateway and infrastructure.

For .NET developers

Protect your APIs with attributes

ErtisAuth.Sdk is a typed client for the ErtisAuth API. ErtisAuth.Sdk.AspNetCore adds authentication and permission checks to your own ASP.NET Core services.

  • Declare the resource, action and object with attributes; placeholders read route values, query parameters, headers and environment variables.

  • A bundled Roslyn analyzer reports invalid permission attributes at compile time.

  • Not on .NET? Every feature is a REST endpoint, so services in any language can verify tokens and check permissions.

[Authorized]
[RbacResource("orders")]
[Route("orders")]
public class OrdersController : ControllerBase
{
	[HttpGet("{id}")]
	[RbacObject("{id}")]
	[RbacAction(Rbac.CrudActions.Read)]
	public IActionResult Get(string id)
	{
		// Reached only when the caller's token grants *.orders.read.{id}
		...
	}
}

NuGet packages

ErtisAuth.SdkVersion v0.0.0
NuGet

A typed .NET client for the ErtisAuth API

dotnet add package ErtisAuth.Sdk
ErtisAuth.Sdk.AspNetCoreVersion v0.0.0
NuGet

Authentication and permission checks for your ASP.NET Core services

dotnet add package ErtisAuth.Sdk.AspNetCore

How it compares

Somewhere between a library and a platform

ErtisAuth is a central, ready-to-run server like the big platforms, but small enough to run next to your own services.

VS Keycloak

A full-featured server, but a heavy Java application configured mostly through its admin console. ErtisAuth keeps the realm idea (memberships) in a small .NET service configured entirely through its API.

VS Auth0, Okta and hosted services

Managed for you, but paid per active user, and your user data lives on a third-party platform. ErtisAuth is self-hosted: the data stays in your MongoDB.

VS Duende IdentityServer

A framework to build your own server with, and most companies need a commercial license. ErtisAuth is a ready-to-run server under the MIT license.

VS ASP.NET Core Identity

A library embedded in each application. ErtisAuth is a central service: many applications, in any language, share the same users and permissions.

Get started

Running in a few minutes

Start ErtisAuth and MongoDB with Docker Compose, create the first membership with the one-time setup endpoint, and sign in.

  1. 1

    Start the containers

    From the root of the repository. The API listens on port 9716, the API reference is at /docs.

    $ git clone https://github.com/ertugrulozcan/ErtisAuth.git
    $ cd ErtisAuth
    $ docker compose up -d --build
  2. 2

    Set up the installation

    Insert a setup token into the database, then call /setup once to create the first membership, role and administrator.

    $ openssl rand -hex 32
    $ docker compose exec mongo mongosh auth \
    	--eval 'db.setup.insertOne({ token: "<setup_token>" })'
    $ curl -X POST http://localhost:9716/setup \
    	-H 'X-Setup-Token: <setup_token>' \
    	-H 'Content-Type: application/json' \
    	-d '{ "membership": { … }, "user": { … } }'
  3. 3

    Get your first token

    Sign in with the administrator and use the access token on any endpoint.

    $ curl -X POST http://localhost:9716/generate-token \
    	-H 'X-Ertis-Alias: <membership_id>' \
    	-H 'Content-Type: application/json' \
    	-d '{ "username": "admin", "password": "<password>" }'

Contributing to the community

ErtisAuth is free and open source under the MIT license. Star the repository, read the docs, or open an issue.