Files
attest/src/attest.ts
T

55 lines
1.6 KiB
TypeScript
Raw Normal View History

2024-05-28 11:00:03 -07:00
import { Attestation, Predicate, Subject, attest } from '@actions/attest'
import { attachArtifactToImage, getRegistryCredentials } from '@sigstore/oci'
2024-11-05 09:16:07 -08:00
import { formatSubjectDigest } from './subject'
2024-05-28 11:00:03 -07:00
2024-06-17 06:51:46 -07:00
const OCI_TIMEOUT = 30000
2024-05-28 11:00:03 -07:00
const OCI_RETRY = 3
export type SigstoreInstance = 'public-good' | 'github'
export type AttestResult = Attestation & {
attestationDigest?: string
}
export const createAttestation = async (
2024-11-05 09:16:07 -08:00
subjects: Subject[],
2024-05-28 11:00:03 -07:00
predicate: Predicate,
opts: {
sigstoreInstance: SigstoreInstance
pushToRegistry: boolean
githubToken: string
}
): Promise<AttestResult> => {
// Sign provenance w/ Sigstore
const attestation = await attest({
2024-11-05 09:16:07 -08:00
subjects,
2024-05-28 11:00:03 -07:00
predicateType: predicate.type,
predicate: predicate.params,
sigstore: opts.sigstoreInstance,
token: opts.githubToken
})
2024-11-05 09:16:07 -08:00
const result: AttestResult = attestation
2024-05-28 11:00:03 -07:00
2024-11-05 09:16:07 -08:00
if (subjects.length === 1 && opts.pushToRegistry) {
const subject = subjects[0]
2024-05-28 11:00:03 -07:00
const credentials = getRegistryCredentials(subject.name)
const artifact = await attachArtifactToImage({
credentials,
imageName: subject.name,
2024-11-05 09:16:07 -08:00
imageDigest: formatSubjectDigest(subject),
2024-05-28 11:00:03 -07:00
artifact: Buffer.from(JSON.stringify(attestation.bundle)),
mediaType: attestation.bundle.mediaType,
annotations: {
'dev.sigstore.bundle.content': 'dsse-envelope',
'dev.sigstore.bundle.predicateType': predicate.type
},
fetchOpts: { timeout: OCI_TIMEOUT, retry: OCI_RETRY }
})
// Add the attestation's digest to the result
result.attestationDigest = artifact.digest
}
return result
}