CA/PKI Backend Project Context
Stack
•	Python 3.13
•	FastAPI (web API)
•	psycopg (PostgreSQL driver)
•	PostgreSQL database: ca
•	Unit tests: unittest
•	HTTP testing: fastapi.testclient
•	Zenroom cryptographic runtime (local execution via Python wrapper)
Run tests:
python3 -m unittest discover
Integration tests require:
export DATABASE_URL="postgresql:///ca"
—————
Project Structure
pki/
├── ca_core/
│   ├── entity.py
│   ├── group_member.py
│   ├── property.py
│   ├── metadata.py
│   ├── db_logging.py
│   └── crypto/
│       ├── zenroom_client.py
│       └── zenroom_service_client.py
│
├── ca_api/
│   ├── app.py
│   └── db.py
│
├── tests/
│   ├── test_entity.py
│   ├── test_group.py
│   ├── test_property.py
│   ├── test_metadata.py
│   ├── test_api_smoke.py
│   ├── test_api_unit.py
│   ├── test_api_integration.py
│   └── integration/
│       └── zenroom tests
│
├── create_tables.sql
└── PROJECT_CONTEXT.md
—————
Architecture
HTTP API (FastAPI)
        │
        ▼
ca_api (thin HTTP adapter)
        │
        ▼
ca_core (business logic)
        │
        ▼
PostgreSQL
The system is layered to keep business logic independent from the HTTP interface.
—————
Database Overview
Database: ca
Core tables:
•	entity
•	group_member
•	property
•	metadata
•	log
Entity Rules
Entity types:
•	person
•	group
•	device
Status values:
•	active
•	revoked
Groups must include ca_reference.
Persons and devices must not include ca_reference.
Revoked entities are immutable.
—————
Logging
All mutations must call:
log_change(cursor, message)
Exactly one log entry must be produced per mutation.
Logging occurs inside the same transaction.
—————
Core Modules
entity.py
Provides:
•	insert_creator
•	enroll_person
•	create_group
•	get_entity
•	set_entity_status
group_member.py
Provides:
•	add_group_member
•	remove_group_member
•	get_members_of_group
property.py
Provides:
•	set_property
•	delete_property
•	get_properties
metadata.py
Provides:
•	get_name
•	get_comment
•	get_public_key
•	get_defense_p
•	set_name
•	set_defense_p
—————
Cryptographic Layer

The system integrates Zenroom as its cryptographic runtime.
Zenroom is a deterministic virtual machine designed for secure execution of
cryptographic protocols defined in Zencode scripts.
In this project Zenroom is executed locally via the official Python wrapper.
No Docker container or HTTP service is used.

ca_core
   └─ crypto
        └─ zenroom_service_client.py
               │
               ▼
        zenroom Python wrapper
               │
               ▼
        Zenroom runtime (local process)

This architecture removes the previous HTTP service layer and simplifies
deployment and testing.

zenroom_service_client.py
zenroom_service_client.py provides the adapter between the CA backend and Zenroom.
Responsibilities:
•	execute Zencode scripts using the Zenroom Python wrapper
•	pass structured JSON input
•	parse Zenroom output
•	normalize results into Python structures
•	translate runtime errors into ZenroomServiceError
All cryptographic operations are exposed through a single client class:

ZenroomServiceClient

Supported Operations
The client provides the following cryptographic operations:
Method	Description	
generate_keypair()	Create an ECDH keypair	
generate_public_key()	Derive public key from keyring	
symmetric_encrypt()	Encrypt message using password	
symmetric_decrypt()	Decrypt password-encrypted message	
asymmetric_encrypt()	Encrypt message for a recipient	
asymmetric_decrypt()	Decrypt message from a sender	
sign_objects()	Sign a string field	
verify_signature()	Verify an ECDH signature	
These operations correspond directly to the Zencode scripts embedded in the module.

Script Execution
All Zencode scripts are executed through a single internal helper:

_run_script()

Responsibilities:
•	invoke zenroom.zencode_exec()
•	pass JSON input
•	capture Zenroom logs
•	parse returned JSON output
•	raise ZenroomServiceError on failure
This centralizes Zenroom interaction and ensures consistent error handling.

Error Handling
Zenroom failures are converted into Python exceptions.

ZenroomServiceError

This exception is raised when:
•	Zenroom execution fails
•	output cannot be parsed
•	expected fields are missing
•	verification fails
This allows the rest of the system to treat cryptographic failures as standard
Python exceptions.

Testing Strategy
Cryptographic functionality is tested using direct functional tests.
Tests execute the real Zenroom runtime through the adapter and verify:
•	key generation
•	encryption/decryption roundtrips
•	signing
•	signature verification
•	signature rejection for tampered messages
Example tests:

tests/test_zenroom_service_client.py

The suite currently contains 9 tests:
 1.	generate keypair
 2.	generate public key
 3.	symmetric encryption
 4.	symmetric decryption
 5.	asymmetric encryption
 6.	asymmetric decryption
 7.	signing
 8.	successful verification
 9.	verification failure for modified message
Tests run with:

python3 -m unittest discover

Typical runtime is under 0.5 seconds.

Security Notes
•	Zenroom scripts execute in an isolated runtime.
•	All inputs are passed as structured JSON.
•	Dynamic script generation restricts field names to safe identifiers.
•	Cryptographic failures are surfaced immediately as exceptions.