File size: 4,618 Bytes
d0a3fab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
<!-- translation: machine + human review pending -->

# SECURITY β€” Picarones (English)

> French version: [`SECURITY.md`](SECURITY.md) (canonical).
> Detailed threat model: [`docs/security/threat-model.md`](docs/security/threat-model.md).
>
> This is a summary translation focused on what an English-speaking
> auditor needs.  The canonical FR version remains authoritative
> for institutional sign-off.  Full alignment scheduled for a
> dedicated human-review sprint.

## Reporting a vulnerability

If you discover a security vulnerability in Picarones, please **do
not file a public GitHub issue**.  Instead, use one of the following
private channels:

- **GitHub Security Advisories** (preferred):
  https://github.com/maribakulj/Picarones/security/advisories/new
- **`/.well-known/security.txt`** on any institutional deployment
  (RFC 9116) β€” the contact address is documented there.

We acknowledge reports within **72 hours** and aim to ship a fix
within **30 days** for HIGH severity issues, **90 days** for MEDIUM.
A coordinated disclosure agreement is offered for non-trivial issues.

## Supported versions

| Version | Status | Security fixes |
|---------|--------|----------------|
| 1.x (current) | Active | Yes |
| 0.x | End of life | No β€” please upgrade |
| Pre-release branches | Best effort | On request |

## Deployment contexts

Picarones is designed for three deployment contexts:

1. **Developer machine** (Codespaces, laptop) β€” local access only,
   relaxed defaults to keep iteration fast.
2. **Institutional server** (intranet, scientific cluster) β€”
   authenticated internal access, with cost guards (rate limit, body
   size limit, max concurrent jobs).
3. **Public space** (HuggingFace Space, online demo) β€” anyone can
   reach the API; cloud API keys (OpenAI, Anthropic, Mistral, Azure…)
   must NOT be exposed to financial DoS.

## Security controls β€” quick reference

| Variable | Default | Effect |
|----------|---------|--------|
| `PICARONES_PUBLIC_MODE` | off | If `1`/`true`, refuses cloud OCR/LLM with shared keys and enables rate limit |
| `PICARONES_MAX_UPLOAD_MB` | `100` | Max upload size in MiB |
| `PICARONES_MAX_CONCURRENT_JOBS` | `2` | Max parallel benchmark jobs (in-process semaphore) |
| `PICARONES_RATE_LIMIT_PER_HOUR` | `5` (public mode) | Max jobs per IP per hour, `0` disables |
| `PICARONES_CSP` | hardened policy | Override Content-Security-Policy |
| `PICARONES_CSRF_REQUIRED` | off | If `1`/`true`, enables CSRF protection (double-submit cookie + HMAC) |
| `PICARONES_CSRF_SECRET` | auto | HMAC secret for CSRF tokens; **must be set in production** |

## In-process middlewares

The `picarones.interfaces.web.security` module provides four
middlewares that institutional operators wire via `create_app(...)`:

- `SecurityHeadersMiddleware` β€” adds CSP, X-Frame-Options,
  X-Content-Type-Options, Referrer-Policy, Permissions-Policy to
  every response.
- `BodySizeLimitMiddleware` β€” rejects requests where
  `Content-Length` exceeds a threshold.  **Known limitation**: does
  not catch `Transfer-Encoding: chunked`; nginx
  `client_max_body_size` is recommended in front.
- `RateLimitMiddleware` β€” sliding window, in-memory,
  `trust_proxy_count: int` for safe `X-Forwarded-For` parsing,
  LRU eviction on `max_clients=10000` to bound memory.
- `AuthenticationMiddleware` β€” opt-in wrapper around an
  `AuthenticationBackend` Protocol; the institution plugs in its
  SSO/LDAP/JWT scheme.

## Audit trail

Sensitive job mutations (`POST /api/jobs`, `DELETE /api/jobs/{id}`)
emit a structured `[audit]` log line at INFO level with the source
IP, ready to be ingested by the institution's SIEM.

## Reproducibility and integrity

`RunManifest` is byte-deterministic (`model_dump_json` with ordered
fields).  The SHA-256 hash of a manifest can be cited in a scientific
publication to anchor the run.  Cryptographic signing of manifests
(Sigstore) is on the roadmap.

## Cloud API key management

Cloud keys (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `MISTRAL_API_KEY`,
`GOOGLE_APPLICATION_CREDENTIALS`, `AZURE_DOC_INTEL_*`) are read from
environment variables only.  Adapters never log keys.  For
institutional deployments, source the env from a secrets vault
(HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, etc.) at
process startup.

See also [`docs/operations/runbook.md`](docs/operations/runbook.md)
for incident response and [`docs/legal/dpa-template.md`](docs/legal/dpa-template.md)
for the data processing agreement template covering cloud
sub-processors.

## Last revised

2026-05.  This document is reviewed at every major release.