Skip to content
VERASPEC
Repository
Security policystable

Security policy

This repository holds two different kinds of thing, and they have two different security postures:

  • The standard — the published artifact sets under standards/ver/, the conformance corpus under conformance/, and the profile validator under packages/ver-validator/. These are the mature deliverables.
  • The reference pipelineservices/verd/, scripts/ and apps/web, the runnable VER-F demo. It is an experimental prototype. See Supported versions before deploying any of it.

Read both sections below before reporting: what counts as a vulnerability in a document is not what counts as one in a program.

Reporting a vulnerability

Report privately through GitHub's security advisories on this repository:

https://github.com/verastd/vera/security/advisories/new (repository → Security tab → Report a vulnerability)

There is no security mailing address for this project. Do not open a public issue for a suspected vulnerability, and do not post a proof-of-concept to the issue tracker or to a pull request before an advisory exists.

Please include, where they apply:

  • which of the two postures above the report concerns (standard, or pipeline);
  • the artifact release (1.0.0, 1.0.1, 1.1-draft) or the commit;
  • for a validator report, the record or fixture that triggers it — the smallest one that still reproduces;
  • for a standards report, the section or $defs entry, and the concrete document a conformant-but-hostile producer could emit under it.

Expectations. This is a single-maintainer project with no service-level agreement. Acknowledgement is on a best-effort basis. If you receive no acknowledgement within 30 days, escalate by opening a non-specific public issue asking the maintainer to check their advisory queue — without details.

Disclosure. Coordinated. Please allow 90 days from acknowledgement before public disclosure, or less by agreement once a fix or a documented disposition has shipped. A finding that ends as a documented disposition rather than a code change is still a resolved finding: this repository's ledger (`docs/standards/VER-1.0-errata.md`) records "documented — not patched" as a real outcome, and a security finding may land there with its rationale stated.

What is in scope

For the standard and the validator:

  • a construction that lets a record be conformant and still misrepresent what it attests (a digest that does not bind what it claims to bind, an identifier that resolves to something other than what a consumer would assume);
  • a validator input that causes a wrong verdict — a nonconformant record reported conformant, or a crash where an indeterminate verdict is owed;
  • a validator input that causes unbounded resource use (a decompression or allocation amplification reachable from a record document).

For the reference pipeline, in-scope reports are limited to defects not already ledgered. The pipeline's known security-relevant defects are catalogued in `docs/standards/VER-1.0-errata.md` §10 and Appendix A; a report restating one of those rows is a duplicate, not a finding.

What is out of scope

  • Anything that requires the attacker to already control the machine running verd, or the contents of .env.
  • Deployment of the reference pipeline to a hostile network or an untrusted input source. That configuration is documented as unsupported below; its failure is expected, not a vulnerability.
  • The absence of authentication, rate limiting, or multi-tenancy in the demo HTTP API beyond what its configuration exposes. It is a demo.
  • Findings against spec/ or standards/ver/1.0.0/ that ask for those files to be edited. They are frozen; see Frozen artifacts.

Supported versions

Standards artifacts

ReleaseStatusSecurity fixes
standards/ver/1.0.1/Current. The corrected published artifact set; its errata annex is normative where it disagrees with the 1.0.0 text.Yes — as a new corrective release directory, never as an edit in place.
standards/ver/1.0.0/Frozen, with its defects. A preservation act. Its defects are catalogued rather than corrected.No. A defect found here is ledgered in `docs/standards/VER-1.0-errata.md` and corrected in a later release.
standards/ver/1.1-draft/Draft, UNRATIFIED. Do not implement against it for production.Yes — draft defects are fixed in the draft. A draft change is not a release.

Records under both 1.0.0 and 1.0.1 declare ver_version: "1.0"; the artifact release version and the record format version are two separate planes (ADR-0001, `VERSIONING.md`). A report that a record format is unsafe therefore applies to both releases at once, and is answered in the release plane.

Frozen artifacts

standards/ver/1.0.0/ and standards/ver/1.0.1/ are immutable published sets. Nothing under them is edited — not to fix a typo, not to correct a digest, and not to fix a security defect. Corrections ship as a new release directory governed by `VERSIONING.md` §3. Unfreezing a published release to meet a later bar would destroy the exact property the freeze provides.

Software

ComponentStatusSecurity fixes
packages/ver-validator (vera-profile/1.0)Supported. The conformance profile validator, the maintained implementation in this repository.Yes, on the current branch. Error codes are an append-only registry (ADR-0003) — a fix never renumbers or reuses a VERxxx code.
services/verd, scripts/, apps/web (the VER-F reference pipeline)EXPERIMENTAL — not for untrusted deployment.Best effort only. Defects are ledgered; not every one is patched.

The reference pipeline must not be deployed where it can be reached by an untrusted network, an untrusted operator, or untrusted input. It exists to demonstrate that the standard is implementable end to end. The owner review of 23 August 2026 (ledgered as REV-01REV-28 in `docs/standards/VER-1.0-errata.md` §10) found, and ruled on, defects of exactly the class that matters here — an unauthenticated ingest path that walked arbitrary server paths, a firehose consumer that advanced its cursor past events it had failed to process, and an index whose collection binding could not tell two embedding spaces apart. That review's remediations are landing on this branch; the honest summary is that the pipeline is under active remediation, not that it is hardened. Treat every input it accepts — uploaded files, firehose events, foreign records — as attacker-controlled, and run it accordingly: on a local machine, against your own photographs.

The same caution applies to the demo HTTP API and the Jetstream consumer in particular: both parse bytes chosen by someone else.

Historical credential exposure

Two live third-party credentials were committed in plaintext to documentation in a sibling project — a separate repository that sits beside this one in the same development environment. They are not in this repository's history, and they are not reproduced here, nor is the file that carried them named: reproducing a leaked secret inside a security policy is the same mistake a second time.

The exposure was reported to the repository owner, who tracks rotation status for both credentials. Anyone who has cloned or mirrored that sibling project's history should assume the values are compromised.

The general rule this project follows, and asks contributors to follow: a credential that has ever been committed is compromised. Rotate it; do not merely delete the line. Removing a secret from the working tree does not remove it from the history, from forks, from mirrors, or from anyone's clone.

Practically, in this repository:

  • .env is git-ignored; .env.example carries no credential values and must never carry one. ATP_IDENTIFIER and ATP_APP_PASSWORD ship empty on purpose. (They ship empty with a trailing comment, which the ledger records as ENV-CREDS-PARSE: a plain cp .env.example .env can leave the parser holding a non-empty nonsense value rather than an empty one. Set both deliberately, or delete the lines.)
  • atproto repositories are public. Publishing is opt-in (PUBLISH=false by default) because a published record is public forever.
  • Use an atproto app password, never an account's main password.
  • Records, thumbnails and vectors under data/ may embed personal content from the photographs ingested. data/ is git-ignored; keep it that way.

Security-relevant design notes

Two properties of the standard are easy to misread as security guarantees and are not:

  • A conformant record is well-formed and self-consistent, not verified. The validator checks structure, referential integrity, the digests the record carries, and signature shape — and, when a public key is supplied, the signature itself. None of that attests that a photograph is what its record says it is, or that the producer is who they claim to be: a valid signature binds a record to a key, and binding that key to a person is a trust decision the profile does not make. "Well-formed" is the claim; "verified" is not.
  • **pixel_hash is a rendered-identity grouping key, not a global primary key.** Two different producers can legitimately hold the same pixel_hash, and asset identity belongs to the deploying system. Treating it as a primary key is how you get one producer overwriting another's record — see the ledger items SPEC-27 and DOCTRINE-PIXHASH-HALF-APPLIED.