Skip to content

seal: the certificate's standing is computed and served, and nothing classifies on it #329

Description

@LKSNDRTMLKV

#322 added cades::certificate_standing: the seal certificate's validity window judged against an attested sealing time, and revocation read from the CRLs the seal carries. It is served on GET /api/v1/dpp/{dppId}/seal and in the evidence dossier.

Nothing decides anything with it. Every surface that produces a verdict still asks only SealBinding — does the seal cover this passport's signature — and that question is indifferent to whether the certificate behind it was revoked or expired when the seal was made.

What that means concretely

A passport sealed with a certificate the CA had already revoked reports, today:

surface reports
GET /api/v1/sealaudit.sound counted as sound
the stored-seal audit's broken 0
evidence dossier qualified_seal check Pass
POST .../seal/repair refused — "this seal verifies"
GET /api/v1/dpp/{id}/sealcertificate revoked

So the one surface that names the problem is the one an operator has to already suspect something to look at. The audit is the surface built for finding what nobody is looking at, and it cannot see this.

SealValidationStatus::of(binding, certificate) already composes both into the right answer — totalFailed / revoked against an attested time, indeterminate / revokedNoPoe without one. It is called on the read route and in the dossier's validation field, and by nothing that classifies.

Where it would go

  • seal_drain::audit_seals_once classifies on inspector.binding(...) alone. SealAudit would need a fifth bucket, and the walk would need certificate_standing per row — which is a second CAdES parse per seal, so the batch/interval arithmetic (SEAL_AUDIT_BATCH, SEAL_AUDIT_INTERVAL_SECS) moves with it.
  • verify::engine::qualified_seal_status matches binding and returns Pass for CoversThisSignature. The dossier already carries certificate, so the verifier has the material without re-reading the seal.
  • The repair route's refusals are binding-shaped. A revoked certificate is not repairable by re-sealing anyway — a replacement would be bought from the same backend under the same certificate — so it wants its own refusal saying that, not admission to the repair path.

Why it is not urgent, and when it stops being deferrable

Every seal this workspace can produce is self-issued by the local backend, whose certificate is minted fresh, never revoked, and valid for its own configured window. The condition is unreachable here.

It becomes reachable the moment a real QTSP credential exists, and the failure is silent in the direction that matters: a passport whose seal is worthless in law counted as sound, in the number an operator reads to decide there is nothing to do.

Worth deciding at the same time

Whether sound keeps its name. It currently means "covers this signature"; with the certificate folded in it would mean "covers this signature and the certificate stood up", and a count that quietly changes meaning between releases is worse than a new one beside it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions