# Changelog

All notable changes to the **GeoEvidence Public API** are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
for SDK packages. **The API itself is versioned by date** (`GeoEvidence-Version: YYYY-MM-DD`)
as locked-down in [`readiness-table-v1.md`](./readiness-table-v1.md) §Política de deprecation.

## Deprecation policy

Breaking changes are announced **6 months in advance** via:

1. Changelog entry under the upcoming version (with the 6-month deprecation date called out).
2. `GeoEvidence-Deprecation-Notice` response header on the affected endpoints during the deprecation window.
3. Direct email to all active integrators.

What counts as a **breaking change** (requires deprecation):
- Removing an endpoint or response field
- Changing the type of a field
- Changing the success status code
- Changing the auth scheme
- Changing the HMAC payload format

What is **NOT breaking** (no deprecation required):
- Adding an optional field
- Adding a new endpoint
- Adding a new header
- Lengthening a string
- Adding an enum value

See [`openapi-public-v1.yaml`](./openapi-public-v1.yaml) for the full contract and
[`auth-spec-v1.md`](./auth-spec-v1.md) for the auth contract.

---

## [2026-09-01] — Initial release

First published version of the GeoEvidence Public API. **Tier: no-ready** per
[`verdict-v1.md`](./verdict-v1.md) — 7 of 9 axes ≥ POC-ready, but critical gaps
in Documentation (SDK, changelog) and Cadenas de custodia / Onboarding kept the
verdict at no-ready. The Doc-axis gaps are being closed in this release.

### Added

- **Architecture: Hybrid deployment** ([ADR-0006](https://github.com/mandres9/GeoEvidence/blob/main/docs/adr/ADR-0006-sub-app-public-api-hybrid.md))
  Sub-app FastAPI mounted at `/api/v1/` on the existing verifier process. No new infrastructure ($0/month added cost). Migrable to a separate gateway service when 10+ partners.
- **Authentication model** ([`auth-spec-v1.md`](./auth-spec-v1.md))
  - Bearer token with `geoev_test_` / `geoev_live_` prefix.
  - HMAC-SHA256 internal signature on each request (`X-GeoEvidence-Signature: t=<unix>,v1=<hex>` over `<ts>.<method>.<path>.<sha256(body_bytes_hex)>`).
  - 1 partner → N API keys (test + live simultaneous).
  - HMAC secret rotation with 24-hour overlap window.
  - Permanent revocation via 5 controlled reasons.
- **Rate limiting**: 1000 requests/hour per partner, sliding window in PostgreSQL.
- **Access log for chain of custody**: every request logged with `partner_id`, `api_key_id`, `request_sha256`, `response_sha256`, `request_id`. Satisfies the POC-ready threshold of the Custodia axis.
- **Standard error shape**: `{code, message, request_id}` with full catalog of 12 error codes documented in the OpenAPI spec.
- **OpenAPI 3.1 specification** ([`openapi-public-v1.yaml`](./openapi-public-v1.yaml)): 6 read-only endpoints + 2 meta. Dual response (JSON/HTML) on `/verify/{id}` with `Accept` content negotiation. Code samples inline per endpoint in cURL, Python, and TypeScript.
- **Public documentation portal**: `/developers/` (Redocly single-page) and `/developers/quickstart` (guided tutorial). Hosted on `geoevidence.com/developers/`.
- **3 CLI scripts** (admin operations):
  - `scripts/issue_api_key.py` — create partner + emit key (outputs key + secret once).
  - `scripts/rotate_hmac_secret.py` — rotate HMAC secret with 24h overlap.
  - `scripts/revoke_api_key.py` — permanently revoke a key (5 reasons).
- **5 PostgreSQL tables** auto-created by `init_db()`: `partners`, `api_keys`, `rate_limit_counters`, `access_log`, `hmac_replay_cache`.
- **6-month deprecation policy** locked-down in [`readiness-table-v1.md`](./readiness-table-v1.md).
- **SDK Python v1.0.0** at `sdks/python/geoevidence-client/` — generated from the OpenAPI spec via `openapi-python-client`. Auto-computes HMAC, handles `Retry-After` retry, raises typed exceptions.

### Security

- Internal HMAC-SHA256 verification prevents bypass attacks against the sub-app edge.
- Forward-compatible scopes catalog (`evidence:read`, `zk_proof:read`, `verify_page:read`, `kaspa:verify`, `*`) — no enforcement in POC-ready (all keys receive `*`).
- Constant-time comparison (`hmac.compare_digest`) for HMAC signature verification.
- Replay window: 5 minutes (anti-reuse of captured signatures) via `hmac_replay_cache` table.
- SHA-256 storage of API keys and HMAC secrets (never stored in plaintext).
- All errors include `request_id` for correlation with internal logs.

### Notes

- The API is **read-only** for external integrators. Internal write endpoints (`/api/geoevidence/hash`, `/anchor`, etc.) remain on the legacy `/api/geoevidence/*` namespace and are not exposed under `/api/v1/`.
- The repo `gti-protocol/` (which contains the cryptographic core) remains private. The library-level `gtip` package is importable via `pip install -e .` from that repo.
- Sandbox URL placeholder: real sandbox environment pending (gap #4 of verdict v1).

---

## [Unreleased]

### Added

- **Bundle PDF endpoint** (`GET /api/v1/verify/{evidence_id}.pdf`) — closes gap #3 of verdict v1
  (Cadena de custodia forense). Devuelve un PDF A4 autosuficiente con metadata,
  server_hash, integrity_match, signature_valid, ZK proof (si existe), link al
  Kaspa tx y un sello de integridad SHA-256 del cuerpo al pie. Implementado con
  `fpdf2` (pure-Python, sin libcairo/libpango) sobre el mismo context que el
  endpoint HTML. Rate-limited y auth-required como el resto del sub-app. Spec
  en `openapi-public-v1.yaml` bajo el tag `Verify`.

_(pending #15 Self-serve test mode endpoint, #16 /version endpoint + SLA doc, #17 Admin endpoint for key issuance, #18 E2E test of auth + HMAC flow)_
