Skip to content

Attestation

An Attestation is an immutable record that a user made a claim about specific Revisions in one Space. An approval is one kind of Attestation. A security review, a reference to a change record in another system, or a test result are others.

The term comes from supply-chain security, where an attestation — in in-toto, SLSA, and Sigstore — is a signed statement about artifacts identified by their digest. A ConfigHub Attestation has the same core: its subjects are Revisions, whose DataHash is their digest, and it records a type of claim and what was claimed. It is not an in-toto statement, and it is not signed; it is recorded by an authenticated user of ConfigHub.

What a change needs before it may be promoted or released is declared separately, as an attestation prerequisite of a ChangeWorkflow. Recording an Attestation changes nothing by itself. It is read when a promotion or a publish that requires it is attempted.

Fields

Field Meaning
Type What is being claimed, such as Approval, SecurityReview, or ChangeRecord. Free-form. Requirements select Attestations by it. Approval is the default, and what cub variant approve records.
Result Pass or Fail. For an Approval, approve or reject. Rejections are kept, since a record of who declined a change is part of the audit trail.
Note The attester's reason, in their own words.
Claims Anything else the attester wants to record, as string keys and values, such as servicenow.com/change=CHG0012345 or a dashboard URL.
ChangeOrderID The ChangeOrder the Attestation was made in the context of. It is context for readers and does not change which Revisions are covered.
ReleaseID A published Release the claim is about.
EvidenceAttestationIDs Other Attestations this one relied on, such as a test result an approver looked at. They may be in other Spaces.
RevokedAttestationID An earlier Attestation this one withdraws.
ExpiresAt After this time, the Attestation no longer satisfies requirements.
UserID The user or service account that recorded it. Set by the server.
CreatedAt When it was recorded. Set by the server.

An Attestation has no Slug, Labels, or Annotations, and is addressed by ID, as a Release is.

Subjects

An Attestation covers one Revision of each of a set of Units in its Space. The Revision is chosen per Unit with the same revision specification the other Unit commands take: a revision number, HeadRevisionNum, LastReleasedRevisionNum, Tag:<tag>, ChangeSet:<changeset>, or ChangeOrder:<changeorder>, any of them optionally prefixed with Before:. Naming a ChangeOrder without a revision selects the Revision its end Tag marks in that Space, which is where the change arrived. The head is the default otherwise. A Unit with no such Revision, such as one the ChangeOrder never reached, is reported as skipped rather than covered at some other Revision, and a selection that covers nothing in a Space records nothing there.

Every subject is in the Attestation's own Space. Approving several Spaces at once, as cub variant approve --change-order ... --stage prod does, records one Attestation per Space.

The binding is to content. A Revision's content never changes, so an Attestation of a Revision is an Attestation of its DataHash. A later Revision of the same Unit with the same DataHash is covered too, so an edit that changes nothing, or a restore to content that was approved before, does not need approving again. A new Revision with different content is not covered by anything until someone attests to it, so nothing has to be cleared or reset when a Unit changes. Coverage does not carry across Units: the same bytes in another variant are a different subject, which keeps an approval of a change in staging from counting as an approval of it in production.

A Revision lists the Attestations covering it in Attestations. cub revision get describes each one, including whether it has been revoked, and cub unit get does the same for the head revision. Filters can read the list:

cub revision list --space payments-prod web --where "LEN(Attestations) > 0"
cub revision list --space payments-prod web --where "Attestations.*.Type = 'Approval'"

Immutability and revocation

There is no update and no delete. Withdrawing an Attestation records a new one whose RevokedAttestationID names it, which only the user who recorded the original, or a user with Manage permission on its Space, can do:

cub attestation revoke 61f26b06-3c34-4363-8b9d-7d0a7c2b5f1c --note "approved the wrong change"

Changing an approval into a rejection is a revocation followed by a rejection. The original stays in the record, so what was claimed and later withdrawn can still be read.

Attestations are deleted only by a recursive delete of their Space. Deleting a Unit removes its Revisions from the Attestations that covered them and leaves the Attestations, which still record the rest of what they covered. See deleting referenced entities.

Permissions

Recording an Attestation of any Type requires the Approve permission on its Space, which the ApproveChildren action grants. The permission decides who may make a claim at all. Whose claims count toward a requirement is decided by the requirement, which can name eligible users and exclude the change's authors. An integration that records Attestations, such as one mirroring change records from ServiceNow, is a service account granted Approve on the Spaces it reports on. An Attestation has Permissions of its own, which, since it is never updated, are set when it is recorded, with --permission on cub attestation create and cub variant approve; its recorder is granted Manage. Reading an Attestation requires View on it, or ViewChildren on its Space.

Commands

  • cub variant approve records Approval Attestations for one or more Spaces, selecting Spaces and Revisions the way promotion and release do. --reject records a rejection, and --note, --claim, --evidence, and --expires-in fill in the record.
  • cub attestation create records an Attestation of any --type in one Space.
  • cub attestation list, get, and revoke read and withdraw them. cub attestation list with no --space lists across the organization:
cub attestation list --where "Result = 'Fail'"

See promoting changes for recording approvals and requiring them in a ChangeWorkflow, and the cub attestation CLI reference.