Metadata-Version: 2.4
Name: authx-identity
Version: 1.1.0
Summary: Standalone OIDC identity microservice and client library for DjangoPlay and Python applications.
Author: CodeFleetX
License-Expression: MIT
Project-URL: Homepage, https://github.com/codefleetx/authx-identity
Project-URL: Repository, https://github.com/codefleetx/authx-identity
Project-URL: Issues, https://github.com/codefleetx/authx-identity/issues
Keywords: authx,oidc,oauth2,identity,authentication,jwt,fastapi,microservice,djangoplay
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Framework :: FastAPI
Classifier: Environment :: Web Environment
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.111.0
Requires-Dist: uvicorn[standard]>=0.29.0
Requires-Dist: sqlalchemy>=2.0.0
Requires-Dist: alembic>=1.13.0
Requires-Dist: asyncpg>=0.29.0
Requires-Dist: psycopg2-binary>=2.9.0
Requires-Dist: passlib[bcrypt]>=1.7.4
Requires-Dist: bcrypt==4.0.1
Requires-Dist: python-jose[cryptography]>=3.3.0
Requires-Dist: cryptography>=42.0.0
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: pydantic>=2.7.0
Requires-Dist: pydantic-settings>=2.2.0
Requires-Dist: email-validator>=2.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: structlog>=24.1.0
Requires-Dist: greenlet>=3.0.0
Provides-Extra: django
Requires-Dist: django>=4.2; extra == "django"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
Requires-Dist: aiosqlite>=0.20.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: build>=1.2.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"
Dynamic: license-file

# authx-identity

**Standalone OpenID Connect (OIDC) identity microservice and Django client for application identity integration.**

* Maintained by: <a href="https://djangoplay.org"> https://djangoplay.org
* Documentation: <a href="https://docs.djangoplay.org">https://docs.djangoplay.org

`authx-identity` provides a standalone FastAPI identity service together with a small Django client library.

AuthX is designed to be an independent identity authority that can be integrated into Django applications and other backend systems.

## Features

* OIDC-style identity endpoints
* Email/password authentication
* SSO identity support
* RS256 JWT access and refresh tokens
* JWKS public-key endpoint
* Local JWT verification
* Server-to-server identity management API
* Django client library
* Stateless token validation
* PostgreSQL persistence
* Alembic migrations
* Configurable JWT issuer and audience
* Provider-independent consumer architecture

## Architecture

AuthX is the identity and JWT authority.

```text
                    AuthX
                      │
          ┌───────────┴───────────┐
          │                       │
       JWT signing             Identity
          │                       │
          ▼                       ▼
     Access tokens          User identities
          │
          ▼
   Consumer applications
          │
          └── verify locally
              using JWKS
```

A consuming application does not need the AuthX private key.

The private signing key remains exclusively inside AuthX.

## Requirements

* Python 3.11 or later
* PostgreSQL
* FastAPI
* SQLAlchemy
* Alembic

A Django application using the client additionally requires Django.

## Installation

Install the AuthX package:

```bash
pip install authx-identity
```

For Django consumers:

```bash
pip install "authx-identity[django]"
```

## Running AuthX

Create a local environment:

```bash
cp env.example .env
```

Generate a new RSA key pair:

```bash
openssl genrsa -out jwt_private.pem 2048

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
```

Verify the public key:

```bash
openssl rsa \
  -in jwt_private.pem \
  -pubout \
  -outform PEM | diff - jwt_public.pem
```

No output indicates a matching public key.

Convert the PEM files into `.env` values:

```bash
awk 'NF {printf "%s\\n", $0}' jwt_private.pem
awk 'NF {printf "%s\\n", $0}' jwt_public.pem
```

Configure:

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

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

AUTHX_SERVICE_TOKEN=<strong-random-secret>
```

Run migrations:

```bash
alembic upgrade head
```

Start AuthX:

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

## Django integration

Configure the Django application with the AuthX service location and verification parameters:

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

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

The service token is required only for trusted backend calls to AuthX's internal API.

The Django application does not require the AuthX private key.

## Identity management

Create or look up identities through the client:

```python
from authx_client import AuthXClient, AuthXConflictError

client = AuthXClient()

try:
    identity = client.create_identity(
        email="user@example.com",
        username="user",
        password="...",
    )
except AuthXConflictError:
    identity = client.get_by_email("user@example.com")
```

## JWT verification

Consumers should verify AuthX tokens locally.

```python
from authx_client import AuthXJWT

payload = AuthXJWT.decode(token)
identity_id = AuthXJWT.get_identity_id(token)
```

JWT verification validates:

* signature
* algorithm
* issuer
* audience
* token validity

The consumer can use AuthX's JWKS endpoint to obtain the public signing key.

## Public API

| Method | Endpoint                            | Purpose              |
| ------ | ----------------------------------- | -------------------- |
| GET    | `/.well-known/openid-configuration` | OIDC discovery       |
| GET    | `/jwks`                             | Public signing keys  |
| POST   | `/token`                            | Issue tokens         |
| POST   | `/token/refresh`                    | Refresh tokens       |
| GET    | `/userinfo`                         | Identity information |

## Internal API

| 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 SSO identity      |
| PATCH  | `/internal/identities/{id}`             | Update identity        |
| DELETE | `/internal/identities/{id}`             | Soft-delete identity   |

Internal endpoints require `X-Service-Token` and are intended for trusted backend services.

## Configuration

| Variable                          | Description                 |
| --------------------------------- | --------------------------- |
| `APP_ENV`                         | Runtime environment         |
| `APP_HOST`                        | Service bind host           |
| `APP_PORT`                        | Service port                |
| `APP_BASE_URL`                    | AuthX service URL           |
| `DATABASE_URL`                    | Async PostgreSQL URL        |
| `DATABASE_URL_SYNC`               | Sync PostgreSQL URL         |
| `JWT_PRIVATE_KEY`                 | RSA private signing key     |
| `JWT_PUBLIC_KEY`                  | RSA public verification key |
| `JWT_ALGORITHM`                   | JWT algorithm               |
| `JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | Access-token lifetime       |
| `JWT_REFRESH_TOKEN_EXPIRE_DAYS`   | Refresh-token lifetime      |
| `JWT_ISSUER`                      | JWT issuer                  |
| `JWT_AUDIENCE`                    | JWT audience                |
| `AUTHX_SERVICE_TOKEN`             | Internal API credential     |
| `CORS_ORIGINS`                    | Allowed browser origins     |

`JWT_ISSUER` and `JWT_AUDIENCE` must be explicitly configured for every deployment.

## Security

Never commit:

* `.env`
* RSA private keys
* service tokens
* database passwords

The AuthX private key must remain inside the AuthX deployment.

Consumer applications should use JWKS/public-key verification rather than receiving the private signing key.

## License

MIT.
