# Security

> Public verification, API key handling, webhook secrets, data integrity links, and disclosure contact.

Philidor exposes public verification surfaces for signed graph decisions and published graph snapshots. Operational security controls are split between API key handling, dashboard sessions, webhook secret storage, and data-integrity checks.

## Signed Decisions

Risk Graph decisions are issued over content-addressed inputs. A decision id is a 64-character hex envelope hash.

Use the public verification endpoint to check the stored envelope and signature chain.

```bash
curl https://api.philidor.io/v1/graph/decision/DECISION_ID/verify
```

The response includes these verification fields.

| Field                    | Meaning                                                           |
| ------------------------ | ----------------------------------------------------------------- |
| `found`                  | Whether the decision id exists                                    |
| `envelopeIntact`         | Whether the stored fields recompute to the expected envelope hash |
| `signatureValid`         | Whether signature recovery succeeds                               |
| `signerRecognized`       | Whether the recovered signer is known                             |
| `signerActiveAtIssuance` | Whether the signer was active when the decision was issued        |
| `decision`               | Decision metadata when present                                    |

Decision metadata includes the portfolio reference, snapshot id, verdict, methodology scope, methodology version, signer address, key id, and creation time.

## Snapshot Manifests

Published graph snapshots can be checked through the public snapshot manifest endpoint.

```bash
curl https://api.philidor.io/v1/graph/snapshot/SNAPSHOT_ID
```

The manifest includes the snapshot id, build time, valid time, builder version, methodology scope, methodology version, node count, edge count, source cursors, and publication lineage.

Snapshot manifests let reviewers connect a signed decision or research figure back to the dataset that was used at issuance time.

## API Keys

Issued API keys use the `pk_live_` prefix and are sent with the `Authorization` header.

```bash
curl -H "Authorization: Bearer pk_live_your_key_here" \
  https://api.philidor.io/v1/vaults?limit=5
```

The backend stores API keys as bcrypt hashes. Validated keys are cached briefly in memory, and deactivated keys can be marked dirty through Redis so processes evict cached entries.

Keys are optional for public read endpoints. Plan-gated write and Decisioning routes require an eligible issued key.

## Webhook Secrets

Basket webhook secrets are returned once at creation. The backend stores the secret in an AES-256-GCM envelope so the dispatcher can recover it for outbound HMAC signing.

Deliveries include `X-Philidor-Signature` in this form.

```text
t=<unix_ts>,v1=<hex>
```

The signed input is the exact string `timestamp.body`, using the raw request body. Receivers should enforce timestamp tolerance and compare signatures in constant time.

See [Webhooks](/docs/guides/webhooks) for delivery behavior, retry behavior, replay, and signature verification.

## Data Integrity

Methodology versioning, score-run provenance, finality rules, source cursors, and oracle freshness are documented in [Data Integrity](/docs/methodology/data-integrity).

The security model depends on these records staying inspectable. A signed graph decision is only useful when the underlying snapshot and methodology references can be reviewed.

## Responsible Disclosure

Report suspected vulnerabilities through the [contact page](https://philidor.io/contact-us). Include affected URLs, request ids where available, reproduction steps, and impact notes.

Do not include secrets, private keys, or live customer data in an initial report.