Skip to content

Latest commit

 

History

History
240 lines (214 loc) · 13.3 KB

DEMO.md

File metadata and controls

240 lines (214 loc) · 13.3 KB

Demo Script

Set-up

Start by installing the CLI:

$ npm install -g @sigstore/cli

Signing

First generate the artifact to be signed:

$ echo "content to be signed" > artifact

Generate a signature for the artifact with the following:

$ sigstore attest artifact -o bundle.json

Created entry at index 30955468, available at
https://search.sigstore.dev?logIndex=30955468

You should see that a browser window is opened to the Sigstore OAuth page. After authenticating with one of the available idenity providers, a signature bundle will be generated and written to the file named "bundle.json".

$ cat bundle.json | jq

{
  "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
  "verificationMaterial": {
    "x509CertificateChain": {
      "certificates": [
        {
          "rawBytes": "MIIC0DCCAlagAwIBAgIUeDHfseinRdn7daK/8Z/FyZbP3bIwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjMwODExMTkxODUzWhcNMjMwODExMTkyODUzWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHxLLliGg8KvMDsipkUeQ7vn9R2MzCnJ2k3R4SHFl/JjY8Sx8hxiBQE2o91Aqz/3zlm3il3YEW19R/nyS/JmWnqOCAXUwggFxMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU/WTuM0/SvrYxbi2eNdzmeu8u9BcwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERYnJpYW5AZGVoYW1lci5jb20wLAYKKwYBBAGDvzABAQQeaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMC4GCisGAQQBg78wAQgEIAweaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGJ5gmOLAAABAMARzBFAiEA4Qda0970UObGop4NGyCF1nqV2elc8735kFIKRdH3KuoCIGIzZ5n+TMs3sC8AvJBpR07Jw/LWF8VGoXoWVWf2GGATMAoGCCqGSM49BAMDA2gAMGUCMFG0aUg0LAgFmsgbjGeKJq/7mC9gO6xBZDAU5w4ioKkE4CunWHGN93v4W6WhiieQuwIxANvAdelWupffNYMInKHNnEodhrMS/R0r7Aauv9v0RMpZU7ucKaQ3qpcL2y3e0WdZaQ=="
        }
      ]
    },
    "tlogEntries": [
      {
        "logIndex": "30955468",
        "logId": {
          "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
        },
        "kindVersion": {
          "kind": "intoto",
          "version": "0.0.2"
        },
        "integratedTime": "1691781533",
        "inclusionPromise": {
          "signedEntryTimestamp": "MEUCIA8Gl6f/EvSd+5t3v8iZOkeaP130qH48lIECNaG8G32jAiEA8BmHu8IGzaxJJiNK6Vx+tr1ZBXzsuGB3uv3dx1P7umk="
        },
        "inclusionProof": {
          "logIndex": "26792037",
          "rootHash": "cQcl3UjHWft0wEVP9BBGd+dKOcmUlaEMIYdC64mNONc=",
          "treeSize": "26792039",
          "hashes": [
            "vKGMQ1vPXwU8c5vyZgfeTPLP4FMUEpTYvXK8tiallMQ=",
            "Wb0EPMtK0MahApzam7tNvIzBUl+q7sKxT804/6NY7gI=",
            "0LvZhb2g5YcpDl5uIxDfQhGkrHGNAu9IFsRYL1XT7ec=",
            "wv1N3YOEW23a2pWHJ26ztTFU9BYAP7K5ub07HXbTVFs=",
            "NaZSOZHPk5+FIJQZ8VsBENYiUi+RauBP/COLsyk6Tro=",
            "jm0lw6HdiXlZ7GboXVWDiQvECU/hnY1hYbzrQrEoZhU=",
            "Be0XOwdJkv66MJS0dgQaI6TS+s8AL4ocQF2cFGMvhs0=",
            "9FWyBkZrudpCTcINV4W2mDTr9e7lXaqrPHlG3xrQKr4=",
            "cacw9L43sGssehTnMe+2LolJXTL9E73sEsxWjfl4DT8=",
            "umCBn5o/ndq+tuxz0bp50E/SrWnOjZXHd6tIWp+ts2s=",
            "jRUq4D8O+FI47Wbw96s7yHCu4qzWUxpIVfxQEeprDmc=",
            "rXEsmEJN4PEoTU8US4qVtdIsGB1MCiRlGOepoiC99kM="
          ],
          "checkpoint": {
            "envelope": "rekor.sigstore.dev - 2605736670972794746\n26792039\ncQcl3UjHWft0wEVP9BBGd+dKOcmUlaEMIYdC64mNONc=\nTimestamp: 1691781533798160174\n\n— rekor.sigstore.dev wNI9ajBEAiAq6zQXfHpGZ9D4aVzzCNt1vUwxQMMpnbfsC0LawPzkpwIgfDHE3XjN4N7zXG6vpN8eXDGqY30jTLojMOjHGFtySuk=\n"
          }
        },
        "canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVU13UkVORFFXeGhaMEYzU1VKQlowbFZaVVJJWm5ObGFXNVNaRzQzWkdGTEx6aGFMMFo1V21KUU0ySkpkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BOZDA5RVJYaE5WR3Q0VDBSVmVsZG9ZMDVOYWsxM1QwUkZlRTFVYTNsUFJGVjZWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWSWVFeE1iR2xIWnpoTGRrMUVjMmx3YTFWbFVUZDJiamxTTWsxNlEyNUtNbXN6VWpRS1UwaEdiQzlLYWxrNFUzZzRhSGhwUWxGRk1tODVNVUZ4ZWk4emVteHRNMmxzTTFsRlZ6RTVVaTl1ZVZNdlNtMVhibkZQUTBGWVZYZG5aMFo0VFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZVdlYxUjFDazB3TDFOMmNsbDRZbWt5WlU1a2VtMWxkVGgxT1VKamQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQwaDNXVVJXVWpCU1FWRklMMEpDVlhkRk5FVlNXVzVLY0ZsWE5VRmFSMVp2V1ZjeGJHTnBOV3BpTWpCM1RFRlpTMHQzV1VKQ1FVZEVkbnBCUWdwQlVWRmxZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRkbG95YkhWTU1qbG9aRmhTYjAxRE5FZERhWE5IUVZGUlFtYzNPSGRCVVdkRkNrbEJkMlZoU0ZJd1kwaE5Oa3g1T1c1aFdGSnZaRmRKZFZreU9YUk1NbmgyV2pKc2RVd3lPV2hrV0ZKdlRVbEhTMEpuYjNKQ1owVkZRV1JhTlVGblVVTUtRa2gzUldWblFqUkJTRmxCTTFRd2QyRnpZa2hGVkVwcVIxSTBZMjFYWXpOQmNVcExXSEpxWlZCTE15OW9OSEI1WjBNNGNEZHZORUZCUVVkS05XZHRUd3BNUVVGQlFrRk5RVko2UWtaQmFVVkJORkZrWVRBNU56QlZUMkpIYjNBMFRrZDVRMFl4Ym5GV01tVnNZemczTXpWclJrbExVbVJJTTB0MWIwTkpSMGw2Q2xvMWJpdFVUWE16YzBNNFFYWktRbkJTTURkS2R5OU1WMFk0VmtkdldHOVhWbGRtTWtkSFFWUk5RVzlIUTBOeFIxTk5ORGxDUVUxRVFUSm5RVTFIVlVNS1RVWkhNR0ZWWnpCTVFXZEdiWE5uWW1wSFpVdEtjUzgzYlVNNVowODJlRUphUkVGVk5YYzBhVzlMYTBVMFEzVnVWMGhIVGpremRqUlhObGRvYVdsbFVRcDFkMGw0UVU1MlFXUmxiRmQxY0dabVRsbE5TVzVMU0U1dVJXOWthSEpOVXk5U01ISTNRV0YxZGpsMk1GSk5jRnBWTjNWalMyRlJNM0Z3WTB3eWVUTmxDakJYWkZwaFVUMDlDaTB0TFMwdFJVNUVJRU5GVWxSSlJrbERRVlJGTFMwdExTMD0iLCJzaWciOiJUVVZaUTBsUlEwTlVhMFo1VG5WcVN6RXpORGRCUkVWVVlucGlWVFpIY0VaNU9VNWtTRzFqV2poSFZuTk5PR3BEUWxGSmFFRk1lVkozT0dzMllrMWllSHAxWnpoaldHeEpiRWhrZWxJeFduZHJjamQxUlU4eE16QjBURVUwTVZKciJ9XX0sImhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIwZmU4NDVmNGRjYmYyZjMzODZlOTFlZGZlZGFiODU1YzY4ZDFhNjYyYzg2NzIzZWEwZTM0NjY4YTNjZDliNTA1In0sInBheWxvYWRIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiOWI3MGE4YTQ4ZTcwOWQzNDlkMzQzMDQyMzI5ZjdkYTZjNDY2MDc2OGM2ODYzMDk3MWNmNTIxOTM5ODk3NWEzNiJ9fX19"
      }
    ],
    "timestampVerificationData": {
      "rfc3161Timestamps": []
    }
  },
  "dsseEnvelope": {
    "payload": "Y29udGVudCB0byBiZSBzaWduZWQK",
    "payloadType": "application/vnd.in-toto+json",
    "signatures": [
      {
        "sig": "MEYCIQCCTkFyNujK1347ADETbzbU6GpFy9NdHmcZ8GVsM8jCBQIhALyRw8k6bMbxzug8cXlIlHdzR1Zwkr7uEO130tLE41Rk",
        "keyid": ""
      }
    ]
  }
}

You'll see that the signature bundle contains the base64-encoded version of the artifact, the generated signature, the signing certificate and metadata about the entry which was made in Rekor.

You can extract and view the signing certificate with the following:

$ cat bundle.json | jq --raw-output '.verificationMaterial.x509CertificateChain.certificates[0].rawBytes' | base64 -d | openssl x509 -inform der -text

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            78:31:df:b1:e8:a7:45:d9:fb:75:a2:bf:f1:9f:c5:c9:96:cf:dd:b2
        Signature Algorithm: ecdsa-with-SHA384
        Issuer: O = sigstore.dev, CN = sigstore-intermediate
        Validity
            Not Before: Aug 11 19:18:53 2023 GMT
            Not After : Aug 11 19:28:53 2023 GMT
        Subject: 
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:1f:12:cb:96:21:a0:f0:ab:cc:0e:c8:a9:91:47:
                    90:ee:f9:fd:47:63:33:0a:72:76:93:74:78:48:71:
                    65:fc:98:d8:f1:2c:7c:87:18:81:40:4d:a8:f7:50:
                    2a:cf:fd:f3:96:6d:e2:97:76:04:5b:5f:51:fe:7c:
                    92:fc:99:96:9e
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage: 
                Code Signing
            X509v3 Subject Key Identifier: 
                FD:64:EE:33:4F:D2:BE:B6:31:6E:2D:9E:35:DC:E6:7A:EF:2E:F4:17
            X509v3 Authority Key Identifier: 
                DF:D3:E9:CF:56:24:11:96:F9:A8:D8:E9:28:55:A2:C6:2E:18:64:3F
            X509v3 Subject Alternative Name: critical
                email:foo@bar.com
            1.3.6.1.4.1.57264.1.1: 
                https://github.com/login/oauth
            1.3.6.1.4.1.57264.1.8: 
                ..https://github.com/login/oauth
            CT Precertificate SCTs: 
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : DD:3D:30:6A:C6:C7:11:32:63:19:1E:1C:99:67:37:02:
                                A2:4A:5E:B8:DE:3C:AD:FF:87:8A:72:80:2F:29:EE:8E
                    Timestamp : Aug 11 19:18:53.228 2023 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:45:02:21:00:E1:07:5A:D3:DE:F4:50:E6:C6:A2:9E:
                                0D:1B:20:85:D6:7A:95:D9:E9:5C:F3:BD:F9:90:52:0A:
                                45:D1:F7:2A:EA:02:20:62:33:67:99:FE:4C:CB:37:B0:
                                2F:00:BC:90:69:47:4E:C9:C3:F2:D6:17:C5:46:A1:7A:
                                16:55:67:F6:18:60:13
    Signature Algorithm: ecdsa-with-SHA384
    Signature Value:
        30:65:02:30:51:b4:69:48:34:2c:08:05:9a:c8:1b:8c:67:8a:
        26:af:fb:98:2f:60:3b:ac:41:64:30:14:e7:0e:22:a0:a9:04:
        e0:2b:a7:58:71:8d:f7:7b:f8:5b:a5:a1:8a:27:90:bb:02:31:
        00:db:c0:75:e9:56:ba:97:df:35:83:08:9c:a1:cd:9c:4a:1d:
        86:b3:12:fd:1d:2b:ec:06:ae:bf:db:f4:44:ca:59:53:bb:9c:
        29:a4:37:aa:97:0b:db:2d:de:d1:67:59:69
-----BEGIN CERTIFICATE-----
MIIC0DCCAlagAwIBAgIUeDHfseinRdn7daK/8Z/FyZbP3bIwCgYIKoZIzj0EAwMw
NzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl
cm1lZGlhdGUwHhcNMjMwODExMTkxODUzWhcNMjMwODExMTkyODUzWjAAMFkwEwYH
KoZIzj0CAQYIKoZIzj0DAQcDQgAEHxLLliGg8KvMDsipkUeQ7vn9R2MzCnJ2k3R4
SHFl/JjY8Sx8hxiBQE2o91Aqz/3zlm3il3YEW19R/nyS/JmWnqOCAXUwggFxMA4G
A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU/WTu
M0/SvrYxbi2eNdzmeu8u9BcwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4Y
ZD8wHwYDVR0RAQH/BBUwE4ERYnJpYW5AZGVoYW1lci5jb20wLAYKKwYBBAGDvzAB
AQQeaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMC4GCisGAQQBg78wAQgE
IAweaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMIGKBgorBgEEAdZ5AgQC
BHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGJ5gmO
LAAABAMARzBFAiEA4Qda0970UObGop4NGyCF1nqV2elc8735kFIKRdH3KuoCIGIz
Z5n+TMs3sC8AvJBpR07Jw/LWF8VGoXoWVWf2GGATMAoGCCqGSM49BAMDA2gAMGUC
MFG0aUg0LAgFmsgbjGeKJq/7mC9gO6xBZDAU5w4ioKkE4CunWHGN93v4W6WhiieQ
uwIxANvAdelWupffNYMInKHNnEodhrMS/R0r7Aauv9v0RMpZU7ucKaQ3qpcL2y3e
0WdZaQ==
-----END CERTIFICATE-----

The SAN in the certificate should match the identity that was used to authenticate with the OAuth provider.

Using the Rekor URL displayed as part of the signing process you should also be able to retrieve the Rekor entry for this signature:

$ curl --silent "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=30955468" \
  | jq --raw-output '.[].body' \
  | base64 --decode \
  | jq

{
  "apiVersion": "0.0.2",
  "kind": "intoto",
  "spec": {
    "content": {
      "envelope": {
        "payloadType": "application/vnd.in-toto+json",
        "signatures": [
          {
            "publicKey": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMwRENDQWxhZ0F3SUJBZ0lVZURIZnNlaW5SZG43ZGFLLzhaL0Z5WmJQM2JJd0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpNd09ERXhNVGt4T0RVeldoY05Nak13T0RFeE1Ua3lPRFV6V2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVIeExMbGlHZzhLdk1Ec2lwa1VlUTd2bjlSMk16Q25KMmszUjQKU0hGbC9Kalk4U3g4aHhpQlFFMm85MUFxei8zemxtM2lsM1lFVzE5Ui9ueVMvSm1XbnFPQ0FYVXdnZ0Z4TUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWRCZ05WSFE0RUZnUVUvV1R1Ck0wL1N2cll4YmkyZU5kem1ldTh1OUJjd0h3WURWUjBqQkJnd0ZvQVUzOVBwejFZa0VaYjVxTmpwS0ZXaXhpNFkKWkQ4d0h3WURWUjBSQVFIL0JCVXdFNEVSWW5KcFlXNUFaR1ZvWVcxbGNpNWpiMjB3TEFZS0t3WUJCQUdEdnpBQgpBUVFlYUhSMGNITTZMeTluYVhSb2RXSXVZMjl0TDJ4dloybHVMMjloZFhSb01DNEdDaXNHQVFRQmc3OHdBUWdFCklBd2VhSFIwY0hNNkx5OW5hWFJvZFdJdVkyOXRMMnh2WjJsdUwyOWhkWFJvTUlHS0Jnb3JCZ0VFQWRaNUFnUUMKQkh3RWVnQjRBSFlBM1Qwd2FzYkhFVEpqR1I0Y21XYzNBcUpLWHJqZVBLMy9oNHB5Z0M4cDdvNEFBQUdKNWdtTwpMQUFBQkFNQVJ6QkZBaUVBNFFkYTA5NzBVT2JHb3A0Tkd5Q0YxbnFWMmVsYzg3MzVrRklLUmRIM0t1b0NJR0l6Clo1bitUTXMzc0M4QXZKQnBSMDdKdy9MV0Y4VkdvWG9XVldmMkdHQVRNQW9HQ0NxR1NNNDlCQU1EQTJnQU1HVUMKTUZHMGFVZzBMQWdGbXNnYmpHZUtKcS83bUM5Z082eEJaREFVNXc0aW9La0U0Q3VuV0hHTjkzdjRXNldoaWllUQp1d0l4QU52QWRlbFd1cGZmTllNSW5LSE5uRW9kaHJNUy9SMHI3QWF1djl2MFJNcFpVN3VjS2FRM3FwY0wyeTNlCjBXZFphUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=",
            "sig": "TUVZQ0lRQ0NUa0Z5TnVqSzEzNDdBREVUYnpiVTZHcEZ5OU5kSG1jWjhHVnNNOGpDQlFJaEFMeVJ3OGs2Yk1ieHp1ZzhjWGxJbEhkelIxWndrcjd1RU8xMzB0TEU0MVJr"
          }
        ]
      },
      "hash": {
        "algorithm": "sha256",
        "value": "0fe845f4dcbf2f3386e91edfedab855c68d1a662c86723ea0e34668a3cd9b505"
      },
      "payloadHash": {
        "algorithm": "sha256",
        "value": "9b70a8a48e709d349d343042329f7da6c4660768c68630971cf5219398975a36"
      }
    }
  }
}

Note that the .spec.content.envelope.signatures[0].sig value matches the signature that was saved to the generated bundle.

Verifying

Use the verify command to make sure that the saved signature matches the artifact:

$ igstore verify bundle.sigstore

Verification succeeded