Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layouts for NPM #1

Open
adityasaky opened this issue Aug 8, 2023 · 2 comments
Open

Layouts for NPM #1

adityasaky opened this issue Aug 8, 2023 · 2 comments

Comments

@adityasaky
Copy link
Member

@feelepxyz and I discussed exploring what an in-toto layout would look like for the NPM use case. This is a general tracking issue for NPM policies <-> in-toto layouts.

Supporting default supply chains

The default layout for NPM must have two steps: build and publish. The build step must be fulfilled by SLSA provenance and the publish step by the NPM publish attestation.

Checks:

  • SLSA provenance claims re builder, source, etc (@feelepxyz can you help enumerate these?)
  • Signature (match against sigstore identity for workflow)
  • CREATE rule for package, DISALLOW *

TODO:

  • Do we need sigstore support in the prototype? Possibly not, we can use test keys and validate using functionaries
  • Paramsub: the CREATE rule and the attribute checks will need param-sub for scalability

Future Work

Once we have a layout working for the default supply chain, we can explore how package maintainers can add steps to their layouts pertaining to various source track checks like test results, code reviews, source repository security controls, etc.

@adityasaky
Copy link
Member Author

adityasaky commented Aug 8, 2023

Okay, I now have a test layout with two steps checked in!

The layout is here: https://github.com/adityasaky/in-toto-attestation-verifier/blob/main/layout-npm.yml

Currently, it looks like:

expires: "2024-10-10T12:23:22Z"
functionaries:
  fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a:
    keyType: "ed25519"
    scheme: "ed25519"
    keyIDHashAlgorithms:
      - "sha256"
      - "sha512"
    keyVal:
      public: "7345b83c121ea0d9ffc3b38d69958718b8435e8cb0552f889d695586693e1b89"
    keyID: "fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a"
steps:
  - name: "build"
    expectedMaterials:
      - "ALLOW git+https://github.com/{github_repository}@{github_ref}"
      - "DISALLOW *"
    expectedProducts:
      - "CREATE pkg:npm/{package_name}@{package_version}"
      - "DISALLOW *"
    expectedPredicates:
      - predicateType: "https://slsa.dev/provenance/v0.2"
        expectedAttributes:
          - rule: "predicate.buildType == 'https://github.com/npm/cli/gha/v2'"
          - rule: "predicate.invocation.configSource.uri == '{config_source}'"
          - rule: "predicate.invocation.configSource.entryPoint == '{entry_point}'"
          - rule: "predicate.invocation.environment.GITHUB_REF == '{github_ref}'"
          - rule: "predicate.invocation.environment.GITHUB_REPOSITORY == '{github_repository}'"
          - rule: "predicate.invocation.environment.GITHUB_REPOSITORY_ID == '{github_repository_id}'"
          - rule: "predicate.invocation.environment.GITHUB_REPOSITORY_OWNER_ID == '{github_repository_owner_id}'"
          - rule: "predicate.invocation.environment.GITHUB_WORKFLOW_REF == '{github_workflow_ref}'"
        functionaries:
          - "fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a"
  - name: "publish"
    expectedMaterials:
      - "MATCH * WITH products FROM build"
      - "DISALLOW *"
    expectedPredicates:
      - predicateType: "https://github.com/npm/attestation/tree/main/specs/publish/v0.1"
        expectedAttributes:
          - rule: "predicate.name == '{package_name}'"
          - rule: "predicate.version == '{package_version}'"
          - rule: "predicate.registry == 'https://registry.npmjs.org'"
        functionaries:
          - "fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a"

I borrowed the example provenance from https://github.blog/2023-04-19-introducing-npm-package-provenance/ and created a publish attestation for the same package. The raw JSON docs are in https://github.com/adityasaky/in-toto-attestation-verifier/tree/main/test-data-npm-raw and I've signed them and checked them in https://github.com/adityasaky/in-toto-attestation-verifier/tree/main/test-data-npm. Finally, I threw together parameter substitution that is currently passed in from another JSON file: https://github.com/adityasaky/in-toto-attestation-verifier/blob/main/parameters/npm-sigstore.json.

The parameters passed in right now are:

{
    "package_name": "sigstore",
    "package_version": "1.2.0",
    "github_ref": "refs/heads/main",
    "github_repository": "sigstore/sigstore-js",
    "github_repository_id": "495574555",
    "github_repository_owner_id": "71096353",
    "github_workflow_ref": "{github_repository}/{entry_point}@{github_ref}",
    "config_source": "git+https://github.com/{github_repository}@{github_ref}",
    "entry_point": ".github/workflows/release.yml"
}

With this, we can now run the verifier.

$ in-toto-attestation-verifier -l layout-npm.yml -a test-data-npm --substitute-parameters parameters/npm-sigstore.json
INFO[0000] Verifying layout expiry...
INFO[0000] Done.
INFO[0000] Substituting parameters...
INFO[0000] Done.
INFO[0000] Fetching verifiers...
INFO[0000] Creating verifier for key fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a
INFO[0000] Done.
INFO[0000] Loading attestations as claims...
INFO[0000] Done.
INFO[0000] Verifying claim for step 'build' of type 'https://slsa.dev/provenance/v0.2' by 'fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a'...
INFO[0000] Applying material rules...
INFO[0000] Evaluating rule `ALLOW git+https://github.com/sigstore/sigstore-js@refs/heads/main`...
INFO[0000] Evaluating rule `DISALLOW *`...
INFO[0000] Applying product rules...
INFO[0000] Evaluating rule `CREATE pkg:npm/[email protected]`...
INFO[0000] Evaluating rule `DISALLOW *`...
INFO[0000] Applying attribute rules...
INFO[0000] Evaluating rule `predicate.buildType == 'https://github.com/npm/cli/gha/v2'`...
INFO[0000] Evaluating rule `predicate.invocation.configSource.uri == 'git+https://github.com/sigstore/sigstore-js@refs/heads/main'`...
INFO[0000] Evaluating rule `predicate.invocation.configSource.entryPoint == '.github/workflows/release.yml'`...
INFO[0000] Evaluating rule `predicate.invocation.environment.GITHUB_REF == 'refs/heads/main'`...
INFO[0000] Evaluating rule `predicate.invocation.environment.GITHUB_REPOSITORY == 'sigstore/sigstore-js'`...
INFO[0000] Evaluating rule `predicate.invocation.environment.GITHUB_REPOSITORY_ID == '495574555'`...
INFO[0000] Evaluating rule `predicate.invocation.environment.GITHUB_REPOSITORY_OWNER_ID == '71096353'`...
INFO[0000] Evaluating rule `predicate.invocation.environment.GITHUB_WORKFLOW_REF == 'sigstore/sigstore-js/.github/workflows/release.yml@refs/heads/main'`...
INFO[0000] Done.
INFO[0000] Verifying claim for step 'publish' of type 'https://github.com/npm/attestation/tree/main/specs/publish/v0.1' by 'fe1c6281c5ff13e35286cc67e5a1fb3e6575b840a6c39ca4267d3805eb17288a'...
INFO[0000] Applying material rules...
INFO[0000] Evaluating rule `MATCH * WITH products FROM build`...
INFO[0000] Evaluating rule `DISALLOW *`...
INFO[0000] Applying product rules...
INFO[0000] Applying attribute rules...
INFO[0000] Evaluating rule `predicate.name == 'sigstore'`...
INFO[0000] Evaluating rule `predicate.version == '1.2.0'`...
INFO[0000] Evaluating rule `predicate.registry == 'https://registry.npmjs.org'`...
INFO[0000] Done.
INFO[0000] Verification successful!

To recap, this is verifying various attributes in provenance using parameter substitution where appropriate, using in-toto artifact rules to ensure the name of the subject, using in-toto artifact rules to match the provenance's subject in the publish attestation, and verifying more attributes in the publish attestation.

I think the layout is also fairly generic. One thing to note is that paramsub isn't supported for functionary constraints so that's something that'll need to be added in for sigstore support. LMK what you think, @feelepxyz!

@adityasaky
Copy link
Member Author

Note: I've moved the layout into the layouts dir.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant