apexauthlib 0.1.11
Apex authorization library for services
Requires Python: >=3.11

# apexauthlib

Private Python library for integrating backend services with the company auth-service.

This library provides:
- **Entities** used across services (user, service, client, service metadata, permissions).
- A **FastAPI router** (`auth_api`) with login endpoints and dependency helpers that inject the current user + metadata from JWT.
- A small **HTTP client wrapper** (`AuthApiProvider` / `AuthApi`) for services to:
  - obtain a token (password login or OAuth code exchange),
  - fetch current user and service-scoped metadata,
  - list users for a service,
  - and register/update service permissions.

> Notes
> - This documentation is best used along with the documentation for auth-service.
> - This is a **private library**. If you change it, you should push to GitHub and then update downstream usage by running `make install` wherever it’s consumed (per team workflow).

---

## Concepts at a glance

### Users
The `User` entity includes:
- `hashed_password`: **must never expose an actual password** through APIs (except in create/update requests handled elsewhere).
- `is_admin`: indicates whether the user is a “superadmin”.

### Service-scoped auth model
The auth model used by services is service-centric:
- Services have a name (`service_name`) and service admins.
- Each service can define **permissions** (schema) and **per-user metadata** values that should align with those permissions.

See: [`docs/concepts.md`](docs/concepts.md)

---

## Usage pattern (high-level)

### 1) Create an `AuthApiProvider`

Example (from service code):

```python
provider = AuthApiProvider[HaccpPermissions](
    http=FluentHttp(
        Httpx.Builder().with_url(AUTH_SERVICE_API).build(),
    ),
    service_name=SERVICE_NAME,
    formatter=DataclassFormatter(HaccpPermissions),
)
```

### 2) Register permissions (service schema)

Example:

```python
provider.for_token(
    provider.login(ADMIN_USERNAME, ADMIN_PASSWORD)
).update_permissions(
    [
        ServicePermission(
            # ...
        )
    ]
)
```

### 3) Add FastAPI auth routes + dependencies

Example:

```python
FastApiBuilder()
.with_title(TITLE)
.with_description(DESCRIPTION)
.with_version(VERSION)
.with_route(auth_api)
.with_dependency(
    auth=provider,
    auth_code=AuthCodeApi(
        http=FluentHttp(
            Httpx.Builder()
            .with_url(AUTH_SERVICE_API)
            .build(),
        ),
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
    ),
)
.build()
```

See: [`docs/fastapi.md`](docs/fastapi.md)

## Known Limitations

### Permission sync is name-based only

AuthApi.update_permissions() compares permissions by name and only creates/deletes.
If a permission keeps the same name but changes type, default, label, etc., 
it currently won’t be updated automatically.

### Admin password dependency for permission registration

The example uses provider.login(ADMIN_USERNAME, ADMIN_PASSWORD) to obtain a token for updating permissions.
If the admin password changes, downstream services must update their configuration, or a more proper flow should
be introduced (e.g., service-to-service auth or code-based admin auth).

### Refresh tokens are not currently handled in this library

Current flow assumes a bearer access token is provided/used. Supporting refresh tokens would enable
longer-lived sessions with automatic token renewal.