> For the complete documentation index, see [llms.txt](https://docs.openg2p.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openg2p.org/platform/platform-services/consent-management/development.md).

# Development

{% hint style="info" %}
**Source repository:** the Consent Manager is developed on **GitLab** — <https://gitlab.com/openg2p/consent-manager>. The former GitHub repository (`github.com/openg2p/consent-manager`) is **frozen and read-only**; its CI is disabled. Clone, raise issues, and open merge requests on GitLab.
{% endhint %}

The Consent Manager is a FastAPI service built on [`openg2p-fastapi-common`](https://github.com/OpenG2P/openg2p-fastapi-common), backed by **PostgreSQL** (async SQLAlchemy). It is the Policy Decision Point (PDP) described in the [design](/platform/platform-services/consent-management/design.md); this section covers building and running it.

## Technology stack

| Concern    | Choice                                                                      |
| ---------- | --------------------------------------------------------------------------- |
| Framework  | `openg2p-fastapi-common` (`BaseService` / `BaseController` / `Initializer`) |
| Language   | Python ≥ 3.10                                                               |
| Database   | PostgreSQL via async SQLAlchemy (`asyncpg`)                                 |
| Migrations | `create_migrate()` per model (no Alembic)                                   |
| Crypto     | `cryptography` (Ed25519 / ES256 / RS256) + canonical-JSON signing           |
| Auth       | Keycloak bearer tokens, validated via JWKS (PyJWT)                          |
| Serving    | gunicorn + uvicorn workers                                                  |

## Repository layout

The service lives under `backend/` in the [`consent-manager`](https://gitlab.com/openg2p/consent-manager) repository (GitLab):

```
backend/src/openg2p_consent_manager/
  config.py            Settings (env prefix CONSENT_MANAGER_)
  db.py                Shared async session factory
  auth.py              Keycloak bearer auth — CallerIdentity, require_role
  models/              SQLAlchemy models (partner, consent, audit)
  schemas/             Pydantic request/response models
  services/            crypto · partner · policy · receipt · verification · consent · lifecycle
  controllers/         verification · well-known · partner · lifecycle · subject
  app.py               Initializer (wires services + controllers, runs migrations)
  main.py              ASGI entrypoint (gunicorn/uvicorn)
  expire.py            Standalone expiry runner (for a CronJob)
```

The HTTP surface is documented in the [API Reference](/platform/platform-services/consent-management/api.md).

## Local setup

```bash
cd backend
cp .env.example .env          # adjust DB, signing key, and auth settings
pip install -e .              # pulls openg2p-fastapi-common + deps
python -m openg2p_consent_manager.main migrate   # create tables
uvicorn openg2p_consent_manager.main:app --reload
```

For local dev without Keycloak, set `CONSENT_MANAGER_AUTH_ENABLED=false` (tokens are then accepted unverified and role checks pass). With no signing key configured, an ephemeral key is generated — fine for dev, but receipts will not verify across restarts.

The whole stack (Postgres + service) also runs via Docker Compose from the repo root:

```bash
docker compose up --build
```

FastAPI serves an interactive OpenAPI/Swagger UI at `/docs` once running.

## Configuration

All settings use the `CONSENT_MANAGER_` env prefix; see `backend/.env.example` for the full list (database, controller id, `.p12` signing key, Keycloak auth, replay window, cache TTL). Key operational settings are summarised in [Deployment](/platform/platform-services/consent-management/deployment.md).

## Background expiry

Consent expiry is **not** an in-process scheduler (so API pods stay stateless). It runs as a standalone command, intended for a Kubernetes CronJob:

```bash
python -m openg2p_consent_manager.expire
```

The validation hot path also lazily expires artefacts on read, so an expired consent is never treated as active even between CronJob ticks.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.openg2p.org/platform/platform-services/consent-management/development.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
