Skip to content

Add dva-vc-manager JWS issue/verify service in place of old ACA-Py - #73

Merged
bzp99 merged 22 commits into
Prometheus-X-association:yassine-refactorfrom
MYRhouma:feat/dva-vc-manager
Aug 6, 2026
Merged

Add dva-vc-manager JWS issue/verify service in place of old ACA-Py#73
bzp99 merged 22 commits into
Prometheus-X-association:yassine-refactorfrom
MYRhouma:feat/dva-vc-manager

Conversation

@MYRhouma

Copy link
Copy Markdown
Contributor

Introduces a standalone FastAPI service that issues and verifies Attestation-of-Veracity JWS credentials.

  • /aov/issue mints an EdDSA-signed JWS with the AoV payload
  • /aov/verify validates the JWS signature and returns {verified: bool, reason?: str}
  • whitelist check runs before payload decode; tampered payloads return verified: false instead of 400
  • 21 unit tests covering whitelist, signing, tamper detection, and error paths (pytest tests/ -> 21 passed)

Depends on: none

@bzp99

Copilot AI review requested due to automatic review settings July 27, 2026 12:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new standalone FastAPI-based “dva-vc-manager” service responsible for issuing and verifying Attestation-of-Veracity (AoV) EdDSA/Ed25519 JWS credentials, including local whitelist management via admin endpoints and a hand-written OpenAPI spec served through a custom Swagger UI.

Changes:

  • Introduces AoV JWS signing/verification utilities, Ed25519 key persistence, and did:key encode/decode support.
  • Adds whitelist repository implementations (in-memory + asyncpg/Postgres) and FastAPI routes for /aov/* and /admin/*.
  • Adds a Docker image, OpenAPI YAML spec, and a pytest suite covering signing/verification/whitelist behavior.

Reviewed changes

Copilot reviewed 20 out of 23 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
dva-vc-manager/uv.lock Locks Python dependencies for the new service.
dva-vc-manager/tests/test_whitelist.py Tests whitelist repository behavior (add/list/remove/find/contains).
dva-vc-manager/tests/test_routes.py End-to-end HTTP tests for /aov/* and /admin/* behavior.
dva-vc-manager/tests/test_keys.py Tests signing key file generation, persistence, and did:key derivation.
dva-vc-manager/tests/test_jws.py Tests JWS signing/verifying + tamper/malformed handling and payload shape.
dva-vc-manager/tests/test_did_key.py Tests did:key codec round-trips and known vector.
dva-vc-manager/tests/init.py Marks test package.
dva-vc-manager/src/dva_vc_manager/whitelist.py Implements FakeWhitelist and PgWhitelist repositories + entry model.
dva-vc-manager/src/dva_vc_manager/signing.py Implements compact JWS encoding/sign/verify and AoV payload builder.
dva-vc-manager/src/dva_vc_manager/routes.py Adds FastAPI routes for AoV issue/verify and admin whitelist/keys.
dva-vc-manager/src/dva_vc_manager/models.py Defines request/response DTOs (camelCase aliases where needed).
dva-vc-manager/src/dva_vc_manager/main.py App factory, Swagger UI serving, and async PgWhitelist bootstrap.
dva-vc-manager/src/dva_vc_manager/keys.py File-backed Ed25519 SigningKeyStore implementation.
dva-vc-manager/src/dva_vc_manager/did_key.py did:key codec implementation for Ed25519 keys.
dva-vc-manager/src/dva_vc_manager/dependencies.py Dependency provider for whitelist repo (singleton).
dva-vc-manager/src/dva_vc_manager/config.py Env-driven runtime configuration + structlog setup.
dva-vc-manager/src/dva_vc_manager/auth.py Bearer-token guard for /admin/* endpoints.
dva-vc-manager/src/dva_vc_manager/init.py Package metadata and high-level module description.
dva-vc-manager/README.md Service overview, usage, and configuration docs.
dva-vc-manager/pyproject.toml Project definition, dependencies, scripts, and pytest config.
dva-vc-manager/Dockerfile Multi-stage container build for the service + spec bundling.
docs/spec/dva-vc-manager.yaml Hand-written OpenAPI spec served by the service.
.gitignore Adds common Python/macOS ignore patterns.
Comments suppressed due to low confidence (1)

docs/spec/dva-vc-manager.yaml:150

  • The OpenAPI spec claims duplicate did_key values return 400, but the implementation (FakeWhitelist.add and PgWhitelist.add) is idempotent and returns the existing entry. The spec should match the actual API behavior (or vice-versa).
        Registers a new trusted attester `did:key`. Returns `201` with the
        created entry on success. Duplicate `did_key` values return `400`.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,176 @@
"""JWS issuance and verification.

Muliberates the production of a compact JWS (``header.payload.signature``)
Comment on lines +157 to +161
Fields are byte-identical to ``hu.bme.mit.ftsrg.dva.api.jws.AovClaims``
(``JwsSigner.kt:19-28``): ``vcId, validSince, subject, issuerId,
recordId, contractId, dataExchangeId, payload``. Python field names
are snake_case but Pydantic aliases make the JSON keys camelCase.
"""
Comment on lines +48 to +51
The DVA API posts the eight claims fields and the veracity-check
results array. The VC Manager decides whether to issue based on
``all_success`` (computed here) and generates a fresh UUID for
the credential.
Comment on lines +27 to +29
import urllib.parse
from datetime import datetime, timezone
from uuid import uuid4
Comment on lines +71 to +74
# Mapped to the camelCase AovClaims fields — AovClaims VC-subject
# JSON keys must stay byte-identical with the Kotlin issuer, so
# we hand the model the snake_case values and rely on the field
# aliases in build_aov_payload.
Comment on lines +5 to +29
import logging

from .config import cfg
from .whitelist import FakeWhitelist, WhitelistRepo

logger = logging.getLogger(__name__)

_whitelist_singleton: WhitelistRepo | None = None


async def get_whitelist() -> WhitelistRepo:
global _whitelist_singleton
if _whitelist_singleton is None:
if cfg.postgres_dsn:
from .main import _build_production_whitelist_async

_whitelist_singleton = await _build_production_whitelist_async()
else:
logger.warning(
"DVA_VC_MANAGER_DB_URL is not set — falling back to "
"FakeWhitelist (in-memory). Verifications will fail-closed "
"until admin populates the whitelist via POST /admin/whitelist."
)
_whitelist_singleton = FakeWhitelist()
return _whitelist_singleton
Comment on lines +93 to +109
async def add(self, did_key: str, label: Optional[str] = None) -> WhitelistEntry:
import json
import asyncpg.exceptions
id = uuid4()
async with self._pool.acquire() as conn:
try:
await conn.execute(
"INSERT INTO did_key_whitelist (id, did_key, label) VALUES ($1, $2, $3)",
id, did_key, label,
)
except asyncpg.exceptions.UniqueViolationError:
existing = await conn.fetchrow(
"SELECT id, did_key, label FROM did_key_whitelist WHERE did_key = $1",
did_key,
)
return WhitelistEntry.from_row(existing)
return WhitelistEntry(id=id, did_key=did_key, label=label)
Comment on lines +21 to +22
from pathlib import Path
from typing import Tuple
Comment thread dva-vc-manager/Dockerfile Outdated
Comment on lines +37 to +39
COPY --from=build --chown=app:app /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=build --chown=app:app /app/src /app/src
COPY --from=build --chown=app:app /app/pyproject.toml /app/pyproject.toml
Comment thread docs/spec/dva-vc-manager.yaml Outdated
openapi: 3.1.0
info:
title: DVA VC Manager
version: 0.3.0
@bzp99 bzp99 self-assigned this Jul 29, 2026
@bzp99 bzp99 changed the title feat: add dva-vc-manager JWS issue/verify service Add dva-vc-manager JWS issue/verify service in place of old ACA-Py Jul 29, 2026
@bzp99
bzp99 force-pushed the feat/dva-vc-manager branch from 93fb65f to 39c123d Compare August 6, 2026 09:14
@bzp99
bzp99 force-pushed the feat/dva-vc-manager branch from 39c123d to 498b5ab Compare August 6, 2026 09:15
@bzp99
bzp99 merged commit 498b5ab into Prometheus-X-association:yassine-refactor Aug 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants