authx-identity
DocsAuthx-Identity

Authx-Identity

A standalone OpenID Connect (OIDC) identity microservice, built with FastAPI, plus a small Django client for services that need to talk to it.

Latest v1.1.1Updated Oct 1, 202619 pages
bash
pip install authx-identity

Start here

The shortest path from nothing to your first result.

  1. 11 min readInstallationThis installs the FastAPI service and its runtime dependencies.

Browse by topic

Grouped the same way as the sidebar.

Works with

Projects that Authx-Identity declares a relationship with in project.json.

Full project README

Python PyPI Downloads License GitHub Release GitHub Stars



AuthX provides a centralized identity authority for applications that need authentication, SSO, JWT issuance, identity management, and local JWT verification without making each application responsible for becoming its own identity provider.


Contents


Overview

AuthX is a standalone identity service implementing an OIDC-oriented authentication architecture.

It provides:

  • Email/password identity management
  • SSO identity support
  • JWT access tokens
  • JWT refresh tokens
  • OIDC discovery
  • JWKS public-key distribution
  • UserInfo
  • Trusted internal identity-management APIs
  • Local JWT verification for consuming applications
  • PostgreSQL-backed identity persistence

The central architectural principle is:

AuthX is the JWT signing authority.

AuthX owns the identity layer while consuming applications remain responsible for their own domain data and business logic.

This allows multiple applications to use the same identity authority without coupling their domain models to the identity service.


What AuthX Provides

Identity Authority

AuthX owns identity information such as:

  • Email addresses
  • Password credentials
  • SSO provider identities
  • Identity status
  • Identity lifecycle

Consuming applications reference an AuthX identity rather than becoming the source of truth for authentication credentials.


Authentication

AuthX supports authentication flows based on:

  • Email/password credentials
  • SSO identity providers
  • Access tokens
  • Refresh tokens

The authentication service is exposed through a FastAPI application.


OpenID Connect Endpoints

AuthX exposes standard discovery and identity endpoints including:

text
/.well-known/openid-configuration
/token
/token/refresh
/userinfo
/jwks
`

These allow clients and consuming services to discover AuthX, obtain tokens, retrieve user information, and verify JWT signatures.


Internal Identity API

Trusted backend applications can use the internal identity API to:

  • Create identities
  • Retrieve identities
  • Find identities by email
  • Find identities by SSO provider and provider ID
  • Update identities
  • Soft-delete identities

Internal identity operations are protected by a service credential.

They are intended for server-to-server communication only.


Package Components

The authx-identity distribution contains two closely related components.

Component Purpose
authx FastAPI identity microservice, database models, API endpoints, and migrations
authx_client Client library for consuming AuthX from Django/Python applications

Install the complete distribution:

bash
pip install authx-identity

For Django applications:

bash
pip install "authx-identity[django]"

A consuming application can use authx_client without running its own AuthX instance.


Architecture

AuthX owns identity and token authority; consuming applications own their domain data, business logic, and authorization.

And DjangoPlay is shown as one consumer, not as something AuthX was specifically designed around.

The architectural boundary is deliberate:

text
AuthX
 └── Identity

Consuming Application
 └── Domain

AuthX does not own application-specific business records.

A consuming application should normally store the AuthX identity ID alongside its own domain data.


Identity Ownership

The system separates identity ownership from domain ownership.

AuthX owns

  • Authentication credentials
  • Identity records
  • SSO identity relationships
  • Identity status
  • JWT issuance
  • JWT signing keys

Consuming applications own

  • Profiles
  • Organizations
  • Roles and application permissions
  • Business entities
  • Financial records
  • Application-specific preferences
  • Domain workflows

Conceptually:

text
                 AuthX Identity
                       │
                 identity_id
                       │
          ┌────────────┴────────────┐
          │                         │
          ▼                         ▼
      DjangoPlay                Other App
      Domain User              Domain User
      Organization             Organization
      Business Data            Business Data

This prevents the identity service from becoming a shared database for unrelated application domains.


Quick Start

Installation

Install AuthX:

bash
pip install authx-identity

For Django consumers:

bash
pip install "authx-identity[django]"

Running the AuthX Service

1. Clone the repository

bash
git clone https://github.com/codefleetx/authx-identity.git
cd authx-identity

Create the environment file:

bash
cp env.example .env

AuthX reads configuration from .env.


2. Generate JWT keys

AuthX uses RSA/RS256 for JWT signing.

Generate a private key:

bash
openssl genrsa -out jwt_private.pem 2048

Generate the corresponding public key:

bash
openssl rsa \
  -in jwt_private.pem \
  -pubout \
  -out jwt_public.pem

Validate the private key:

bash
openssl rsa \
  -in jwt_private.pem \
  -check \
  -noout

Expected:

text
RSA key ok

3. Configure the PEM values

AuthX accepts the PEM keys through environment variables.

The .env representation should contain literal \n sequences between PEM lines:

env
JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"

The settings layer converts these literal sequences into actual newlines before loading the keys.

Do not expose or commit the private key.


4. Configure JWT settings

Example:

env
JWT_ALGORITHM=RS256

JWT_ACCESS_TOKEN_EXPIRE_MINUTES=60
JWT_REFRESH_TOKEN_EXPIRE_DAYS=30

JWT_ISSUER=https://auth.example.com
JWT_AUDIENCE=your-application

Issuer

JWT_ISSUER identifies the AuthX deployment issuing the token.

It must be a valid HTTP(S) URL without:

  • Query strings
  • URL fragments

Production deployments must use HTTPS.

Example:

env
JWT_ISSUER=https://auth.djangoplay.org

Audience

JWT_AUDIENCE identifies the intended consumer of the token.

Example:

env
JWT_AUDIENCE=djangoplay

The consuming application must validate the expected issuer and audience.


5. Configure the service token

Internal identity APIs require:

env
AUTHX_SERVICE_TOKEN=<strong-random-secret>

Generate a strong value:

bash
python -c "import secrets; print(secrets.token_hex(48))"

This credential is strictly backend-only.

Never expose it to:

  • Browsers
  • Frontend JavaScript
  • Mobile applications
  • End users
  • Public API clients

6. Configure PostgreSQL

Example:

env
DATABASE_URL=postgresql+asyncpg://authx:<password>@127.0.0.1:5432/authx

DATABASE_URL_SYNC=postgresql+psycopg2://authx:<password>@127.0.0.1:5432/authx

When running PostgreSQL through Docker Compose, the hostname can be the database service name instead.


7. Configure CORS

CORS origins are configured as a comma-separated list:

env
CORS_ORIGINS=http://localhost:3000,https://example.com

Only include origins that actually require browser access to AuthX.


8. Run migrations

bash
alembic upgrade head

9. Start AuthX

For development:

bash
uvicorn authx.main:app \
  --host 0.0.0.0 \
  --port 8100

AuthX defaults to:

text
http://localhost:8100

10. Verify the service

Health check:

bash
curl http://localhost:8100/health

Expected:

json
{
  "status": "ok",
  "service": "authx"
}

OIDC discovery:

bash
curl http://localhost:8100/.well-known/openid-configuration

JWKS:

bash
curl http://localhost:8100/jwks

Using AuthX from Django

Install the Django extra:

bash
pip install "authx-identity[django]"

Configure the Django application:

python
AUTHX_BASE_URL = "https://auth.example.com"
AUTHX_SERVICE_TOKEN = "..."

AUTHX_JWT_ALGORITHM = "RS256"
AUTHX_JWT_AUDIENCE = "your-application"
AUTHX_JWT_ISSUER = "https://auth.example.com"

The Django application does not need the AuthX private key.

It should only have access to:

  • AuthX's public key
  • AuthX JWKS
  • Its own service credential where internal APIs are required

Creating an identity

A backend consumer can use the client:

python
from authx_client import AuthXClient

client = AuthXClient()

identity = client.create_identity(
    email="user@example.com",
    username="user",
    password="...",
)

An existing identity can be looked up:

python
identity = client.get_by_email("user@example.com")

The exact client API should be treated as the integration boundary rather than calling AuthX's HTTP endpoints directly throughout the application.


API

Public Endpoints

Method Endpoint Purpose
GET /.well-known/openid-configuration OIDC discovery
GET /jwks Public JWT signing keys
POST /token Issue access and refresh tokens
POST /token/refresh Refresh an access token
GET /userinfo Retrieve authenticated identity information

Internal Endpoints

Internal identity endpoints require the configured service credential.

Method Endpoint Purpose
POST /internal/identities Create identity
GET /internal/identities/{id} Retrieve identity
GET /internal/identities/by-email/{email} Find identity by email
GET /internal/identities/by-sso/lookup Find identity by SSO provider and ID
PATCH /internal/identities/{id} Update identity
DELETE /internal/identities/{id} Soft-delete identity

These endpoints are designed for trusted backend services.


Configuration

AuthX configuration is environment-based.

Application

Variable Purpose Default
APP_ENV Runtime environment development
APP_HOST Bind host 0.0.0.0
APP_PORT Service port 8100
APP_BASE_URL AuthX base URL http://localhost:8100

Database

Variable Purpose
DATABASE_URL Async SQLAlchemy/PostgreSQL connection
DATABASE_URL_SYNC Synchronous PostgreSQL connection used for migration tooling

JWT

Variable Purpose Default
JWT_PRIVATE_KEY RSA private signing key Required
JWT_PUBLIC_KEY RSA public key Required
JWT_ALGORITHM JWT signing algorithm RS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES Access-token lifetime 60
JWT_REFRESH_TOKEN_EXPIRE_DAYS Refresh-token lifetime 30
JWT_ISSUER JWT issuer Required
JWT_AUDIENCE JWT audience Required

Internal API

Variable Purpose
AUTHX_SERVICE_TOKEN Backend service authentication

CORS

Variable Purpose Default
CORS_ORIGINS Allowed browser origins http://localhost:3000

JWT Verification

AuthX signs JWTs using its RSA private key.

Consumers verify those tokens using AuthX's public key or JWKS.

text
                 AuthX
                   │
                   │
             Private Key
                   │
                   ▼
              Sign JWT
                   │
                   ▼
                JWT
                   │
                   ▼
          Consumer Application
                   │
                   │ verify
                   ▼
             Public Key
              /  JWKS

The AuthX private key must remain inside the AuthX deployment.

Consumers should never receive:

text
JWT_PRIVATE_KEY

They should instead use:

text
JWT_PUBLIC_KEY

or:

text
/jwks

Required JWT validation

Consumers should validate:

  • Signature
  • Algorithm
  • Expiration (exp)
  • Issuer (iss)
  • Audience (aud)

The expected issuer and audience must be explicitly configured by the consuming application.


Security Model

AuthX has two important security boundaries.

1. JWT signing boundary

Only AuthX owns the JWT signing private key.

text
                  ┌─────────────────┐
                  │      AuthX      │
                  │                 │
                  │ Private Key     │
                  │       │         │
                  │       ▼         │
                  │   Sign JWT      │
                  └───────┬─────────┘
                          │
                          ▼
                         JWT
                          │
                          ▼
                   Consumer Apps
                          │
                          ▼
                   Verify locally

This makes AuthX the single JWT signing authority.


2. Internal API boundary

The internal identity API requires:

text
X-Service-Token

The service token is intended for trusted backend-to-backend communication.

It must never be sent to an untrusted client.


Private key protection

Never commit:

text
jwt_private.pem
.env
JWT_PRIVATE_KEY

to source control.

If a private signing key is exposed, it should be treated as compromised and replaced.


Database

AuthX uses PostgreSQL for persistent identity data.

The service uses:

  • SQLAlchemy
  • Async PostgreSQL access
  • Synchronous PostgreSQL access for migration tooling
  • Alembic migrations

The database belongs to AuthX.

Consuming applications should not directly read or write the AuthX database.

The correct integration boundary is:

text
Consumer Application
        │
        ▼
   AuthX Client
        │
        ▼
    AuthX API
        │
        ▼
 AuthX PostgreSQL

Production Deployment

AuthX is designed to run as a standalone service.

A typical deployment can use:

text
Internet
   │
   ▼
Reverse Proxy
   │
   ▼
AuthX
   │
   ▼
PostgreSQL

When deployed alongside DjangoPlay:

text
                    Cloudflare
                        │
                        ▼
                      Nginx
                   ┌────┴────┐
                   │         │
                   ▼         ▼
              DjangoPlay   AuthX
                   │         │
                   ▼         ▼
              PostgreSQL  PostgreSQL

AuthX should normally run behind the production reverse proxy rather than exposing the application server directly to the Internet.

Internal identity-management endpoints should be protected from unauthorized public access.


Production environment

Production should use:

env
APP_ENV=production

JWT_ISSUER=https://auth.example.com
JWT_AUDIENCE=your-application

JWT_ALGORITHM=RS256

Because production mode requires the JWT issuer to use HTTPS:

text
https://...

is required for JWT_ISSUER.


Development

Install the development dependencies:

bash
pip install -e ".[dev]"

Run the test suite:

bash
pytest

Run linting:

bash
ruff check .

Build the package:

bash
python -m build

Validate the distributions:

bash
twine check dist/*

Package Information

Current package:

text
authx-identity

Current release:

text
1.1.0post1

Python support:

text
Python >= 3.11

The distribution contains:

text
authx
authx_client

Project Structure

The package is organized broadly as:

text
authx/
│
├── authx/
│   ├── api/
│   ├── core/
│   ├── db/
│   ├── middleware/
│   └── models/
│
├── authx_client/
│
├── alembic/
│
├── tests/
│
├── static/
│
├── Dockerfile
├── docker-compose.yml
├── docker-compose.fullstack.yml
├── pyproject.toml
├── CHANGELOG.md
├── LICENSE
├── NOTICE
├── PyPI.md
└── README.md

The microservice and client are distributed together so consuming applications can install the integration client from the same package.


Relationship with DjangoPlay

DjangoPlay uses AuthX as its external identity authority.

The architectural relationship is:

text
                    AuthX Identity
                         │
              Authentication / JWT
                         │
                         ▼
                  DjangoPlay
                         │
          ┌──────────────┼──────────────┐
          ▼              ▼              ▼
       Users        Policy Engine    Domain Apps
                                      │
                         ┌────────────┼────────────┐
                         ▼            ▼            ▼
                     Finance      Helpdesk     Entities

DjangoPlay owns its application-domain data.

AuthX owns identity.

This separation allows AuthX to serve DjangoPlay and other applications without making those applications share their domain databases.


Documentation

The README provides the primary installation and architectural overview.

Additional project documentation is maintained in the repository, including:

  • CHANGELOG.md
  • PyPI.md
  • API documentation
  • Deployment configuration
  • Infrastructure configuration

License

MIT License.

See LICENSE and NOTICE.