openapi: 3.2.0 info: title: imgauth — API di attestazione opere digitali Hash API version: 1.34.1 description: 'Motore di attestazione Spazio Genesi ETS. Full privacy: l''impronta SHA-256 si calcola sul client, il file non viene mai inviato al server. Contratto reale in italiano (non tradurre i nomi campo). Vedi https://attestazione.spaziogenesi.org per l''interfaccia utente e https://github.com/SPAZIO-GENESI/imgauth per il codice sorgente (AGPL-3.0).' contact: name: Spazio Genesi ETS url: https://spaziogenesi.org license: name: AGPL-3.0-only url: https://github.com/SPAZIO-GENESI/imgauth/blob/main/LICENSE servers: - url: https://imgauth.spaziogenesi.org description: produzione tags: - name: Hash paths: /api/hash: post: summary: Attesta un'impronta SHA-256 description: 'Percorso primario (dalla 1.15.0): riceve l''impronta calcolata sul client (full privacy). Percorso legacy: file inline base64 in `image` (hash calcolato dal server, tetto 100 MB). Se assente una credenziale agente valida (vedi agentBearer), è richiesto `turnstile_token` quando TURNSTILE_SECRET è configurato.' security: - agentBearer: [] - voucherHeader: [] - {} requestBody: required: true content: application/json: schema: type: object properties: sha256: type: string pattern: ^[0-9a-f]{64}$ description: Impronta calcolata sul client (percorso primario) image: type: string format: byte description: File inline base64 (percorso legacy, tetto 100 MB) name: type: string type: type: string description: MIME dichiarato size: type: integer description: Dimensione dichiarata in byte (solo percorso client) titolo: type: string maxLength: 150 autore: type: string maxLength: 100 anno: type: string maxLength: 50 note: type: string maxLength: 300 turnstile_token: type: string description: Richiesto se non c'è credenziale agente e TURNSTILE_SECRET è configurato lang: type: string enum: - it - en description: Lingua dei messaggi d'errore (P41). Facoltativo, default 'it'; in mancanza si legge Accept-Language. Non influisce sul contenuto attestato né sulla firma HMAC. responses: '200': description: Attestazione emessa content: application/json: schema: type: object properties: sha256: type: string dimensione_bytes: type: - integer - 'null' tipo_mime: type: string titolo: type: string autore: type: string anno: type: string note: type: string timestamp_iso: type: string format: date-time timestamp_leggibile: type: string attestazione: type: string emesso_da: type: string hmac: type: - string - 'null' fascia: type: string enum: - base - sviluppatore - convenzione description: Fascia effettiva dell'emissione (P25) fascia_motivo: type: - string - 'null' enum: - null - pool_esaurito - tetto_individuale description: Presente solo se una convenzione è stata degradata a 'base' convenzione: type: - object - 'null' properties: id: type: string name: type: string description: Presente solo se fascia è 'convenzione' '400': description: Campo mancante o malformato content: application/json: schema: $ref: '#/components/schemas/Errore' '403': description: Credenziale agente invalida, o verifica anti-bot non superata content: application/json: schema: $ref: '#/components/schemas/Errore' '413': description: File troppo grande (solo percorso legacy, max 100 MB) content: application/json: schema: $ref: '#/components/schemas/Errore' '429': description: Quota credenziale esaurita, o rate limit per-IP (60/60s) content: application/json: schema: $ref: '#/components/schemas/Errore' tags: - Hash components: schemas: Errore: type: object properties: error: type: string securitySchemes: agentBearer: type: http scheme: bearer bearerFormat: sg_k__ oppure sg_s__ description: 'Credenziale agente (P21): API key per convenzioni o session token da device flow. Sblocca SOLO il bypass della challenge Turnstile su POST /api/hash — HMAC, timestamp server e rate limit per-IP restano invariati. Facoltativa: senza header, il percorso Turnstile è identico a prima.' voucherHeader: type: apiKey in: header name: X-SG-Voucher description: 'Voucher firmato stateless (P25 §2.7): ottenuto SOLO tramite il flusso OAuth "Attesta con la tua email" sul sito — non c''è un endpoint pubblico in questo contratto che lo emette. TTL 8h. Bypassa il solo Turnstile su /api/hash e /api/cert-pdf, applica pool/tetto di un''eventuale convenzione o la fascia Professionale — stesso principio del bearer agente.'