Omejdn is a minimal but extensible OAuth 2.0/OpenID connect server used for ...
- IoT devices which use their private keys to request OAuth2 access tokens in order to access protected resources
- Websites or apps which retrieve user attributes
It is used as the Dynamic Attribute Provisioning Service (DAPS) prototype of the Industrial Data Space.
Some of Omejdn's core features include:
- Database-free easy-to-read configuration files
- Integration of existing LDAP directory services
- Fully configurable through the Admin API Plugin
- A User Selfservice API Plugin
- Standard Compliance (see below)
IMPORTANT: Omejdn is meant to be a research sandbox in which we can (re)implement standard protocols and potentially extend and modify functionality under the hood to support research projects. Use at your own risk! At a minimum, take a look at the documentation for production setups.
The main configuration file is config/omejdn.yml
.
It will be generated when you first run Omejdn.
The default values result in a plain OAuth 2.0 server with no OpenID support
and no way to add users via an API, served at http://localhost:4567
Depending on your use case, you might want to at least configure the following options:
issuer: https://example.org
defines Omejdn's Issuer Identifier. It is used for finding Omejdn's endpoints.front_url: https://example.org/auth
should point to where Omejdn is mounted. Defaults toissuer
above. If the two values differ or have a path segment, make sure to relay the well-known endpoints for the issuer according to the documentation.openid: true
enables OpenID functionalityaccept_audience
should include the issuer identifier and$front_url/token
. Delete this config option to generate a default one for your setup.
To start Omejdn, simply execute
$ bundle config set --local with omejdn
$ bundle config set --local without plugins development # Include these for more complex setups and development
$ bundle install
$ ruby omejdn.rb
You may now add clients and users as decribed below, and request access tokens for them.
The token endpoint is /token
and the authorization endpoint is /authorize
,
as advertised at /.well-known/oauth-authorization-server
.
For testing purposes, a script for creating JWT Bearer Tokens for client authentication is located at scripts/create_test_token.rb
.
This section provides but a very brief overview of the possible configuration options.
When in doubt, take a look at the documentation in /docs
.
By default, all configuration options are specified in files under /config
and /keys
.
Omejdn's Plugin system however allows them to be located almost anywhere (including databases, remote locations, ...).
The server public/private key pair used to sign tokens is located at keys/omejdn/omejdn.key
in PEM format.
This file will be auto-generated, if it does not exist.
If you would like to use your own key, simply replace this file.
You may place other keys and certificates in this folder to have the keys be advertised via the JWKS endpoint (e.g. for key rollover).
Clients are configured in config/clients.yml
using the client registration parameters.
A minimal public client needs to have
- a unique
client_id
- a
token_endpoint_auth_method
with a value ofnone
- at least one value listed under
redirect_uris
- at least one value listed under
scope
Users are configured in config/users.yml
.
Each user has at least a username
, password
, and an empty array of attributes
,
which are (in their simplest form) key-value pairs describing information about the user. For instance:
- key: given_name
value: Alice
For more complex setups take a look at the documentation.
A client can request any subset of scopes in his scopes
, configurable in the client configuration file.
If you define a set of attributes for a scope in config/scope_mapping.yml
,
the userinfo
endpoint response will also include this attribute for OpenID requests.
(Note: You can also add those attributes to the Access- and ID Tokens.
Have a look at the attributes
claim mapper plugin.)
Scopes of the form k:v
are granted if the resource owner (the user in authorization code flows) contains an attribute with key k
and value v
.
Other scopes are granted if the resource owner contains at least one attribute which the scope under consideration maps to.
See the documentation for details.
In config/scope_description.yml
you can configure a short description string
which is displayed to the user in an OpenID Connect flow upon requesting authorization.
There are some special predefined scopes you may want to use:
openid
,profile
,email
: These scopes are defined by OpenID.omejdn:*
: These scopes are reserved for use with Omejdn and its APIs. Values include:omejdn:read
andomejdn:write
for access to the User Selfservice API Plugin.omejdn:admin
for access to the Omejdn Admin API Plugin.
Omejdn's functionality can be customized through the use of plugins. For more information please take a look at the documentation.
Omejdn comes with its own Docker images, which you can either grab from ghcr.io, or build yourself like so:
$ docker build . -t my-omejdn-server
$ docker run -d --name=omejdn -p 4567:4567 \
-v $PWD/config:/opt/config \
-v $PWD/keys:/opt/keys my-omejdn-server
Most of Omejdn's core features (excluding plugins) can be configured via environment variables, by upper-casing the config option and prepending OMEJDN_
.
For instance, setting OMEJDN_ISSUER
will overwrite the issuer
configuration option.
To add an admin user, set OMEJDN_ADMIN
to username:password
.
This server mostly implements the following standards (potentially via plugins):
- Web Authorization Protocol (oauth)
- RFC 6749 - The OAuth 2.0 Authorization Framework
- RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage
- RFC 7519 - JSON Web Token (JWT)
- RFC 7521 - Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants
- RFC 7523 - JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
- RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients
- RFC 8414 - OAuth 2.0 Authorization Server Metadata
- RFC 8707 - Resource Indicators for OAuth 2.0
- RFC 9068 - JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
- RFC 9101 - The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)
- RFC 9126 - OAuth 2.0 Pushed Authorization Requests
- RFC 9207 - OAuth 2.0 Authorization Server Issuer Identification
- OpenID Connect Protocol Suite
- Other Standards
- RFC 7033 - WebFinger
- Internet Drafts
NOTE: Omejdn only implements two grant types:
client_credentials
for RFC7523.authorization_code
for OpenID Connect.
In particular, it does not implement the JWT bearer authorization grant or the Implicit Grant.
The only OpenID Connect authorization flow supported is the authorization code flow (with or without PKCE). As specified in the OAuth2 Security Best Current Practice Document, these are the only grant types we will likely support for OAuth2.0 and OpenID Connect.
Omejdn uses the following directory structure:
\_ omejdn.rb (Omejdn Source code)
\_ lib/ (Additional Source code)
\_ plugins/ (Plugin Source code)
\_ config/
\_ omejdn.yml (The main configuration file)
\_ clients.yml (Client configuration file)
\_ webfinger.yml (Webfinger configuration)
\_ oauth_providers.yml (To configure external OpenID Providers)
\_ scope_description.yml (Human-readable strings for Scopes)
\_ scope_mapping.yml (Mapping Scopes to Attributes)
\_ keys/
\_ omejdn/ (Keys and Certificates to be JWKS-advertised)
\_ omejdn.key (The OAuth2 server private key)
\_ clients/ (The public key certificates for clients)
\_ views/ (Web-Pages)
\_ public/ (Additional frontend resources (CSS+Images))
\_ docs/ (Documentation)
\_ tests/
\_ test_*.rb (Unit and E2E tests for Omejdn)
\_ test_resources/ (Test vectors)
\_ scripts/ (Convenience Scripts)