Compare commits
137 Commits
attest-pro
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
329e85366b | ||
|
|
1f6530b126 | ||
|
|
edaf7eaa6a | ||
|
|
c83dfaf9c9 | ||
|
|
6a8358e0d0 | ||
|
|
1f19cb823d | ||
|
|
c86dc3b451 | ||
|
|
aa5b10565a | ||
|
|
c5ece432ed | ||
|
|
d1d9c2f6ce | ||
|
|
b014017b9a | ||
|
|
c9aeb94c1d | ||
|
|
56874d0b3a | ||
|
|
05fee12fb7 | ||
|
|
f201da94aa | ||
|
|
e291536024 | ||
|
|
30a04788f0 | ||
|
|
61238cc62d | ||
|
|
8a9489fcad | ||
|
|
425161028f | ||
|
|
bd022b3e91 | ||
|
|
0500d190bc | ||
|
|
1f796e3f26 | ||
|
|
243dfbcc87 | ||
|
|
395b5fe114 | ||
|
|
2856a952d5 | ||
|
|
677bfa4a68 | ||
|
|
1aa89f25f0 | ||
|
|
a59d6f4390 | ||
|
|
ccb74b9fb7 | ||
|
|
de6b67b3e0 | ||
|
|
cee30c25dd | ||
|
|
14f0adcaeb | ||
|
|
8c3fad614c | ||
|
|
7ccdc8c0d2 | ||
|
|
4e768795ee | ||
|
|
3f2789eea1 | ||
|
|
005a4945ec | ||
|
|
2d4538d531 | ||
|
|
4bdeb94f2c | ||
|
|
7d33fc6e40 | ||
|
|
91de02cd75 | ||
|
|
2bfd8b6229 | ||
|
|
d043f700cf | ||
|
|
1fce13823c | ||
|
|
f635a16795 | ||
|
|
66453b04e5 | ||
|
|
81d5d173f1 | ||
|
|
b98dcfcf7b | ||
|
|
8729fdfa22 | ||
|
|
7716319800 | ||
|
|
0704470d46 | ||
|
|
947c9a8cb4 | ||
|
|
76d5f57447 | ||
|
|
d1eddd594d | ||
|
|
5e97ee0163 | ||
|
|
c30fa57d5c | ||
|
|
1edee384ef | ||
|
|
79aa16901d | ||
|
|
6b99024a27 | ||
|
|
eeeceddac4 | ||
|
|
0d78cf9272 | ||
|
|
cf8a93a0bf | ||
|
|
2fc4c161f5 | ||
|
|
cdb0e2e83a | ||
|
|
870b54ced2 | ||
|
|
3173992fa5 | ||
|
|
367c3c8fa4 | ||
|
|
950895441e | ||
|
|
cd2679a04a | ||
|
|
90f5852a17 | ||
|
|
b5dbce5662 | ||
|
|
de8cf19d01 | ||
|
|
e39de4a1bc | ||
|
|
95616b460a | ||
|
|
62ada11e35 | ||
|
|
cc4b2a3506 | ||
|
|
c7e0b1e9ae | ||
|
|
65a4578504 | ||
|
|
932f3688fb | ||
|
|
4be015fd40 | ||
|
|
59dfb5cbf7 | ||
|
|
77dd3aa016 | ||
|
|
f2196e3c9a | ||
|
|
1ecf2c1898 | ||
|
|
c5c6172823 | ||
|
|
0a60e5fdd5 | ||
|
|
f1a940310f | ||
|
|
0e7dbbbfd9 | ||
|
|
62297ee17e | ||
|
|
63688fec32 | ||
|
|
f3a83c2db9 | ||
|
|
0fcddcdda7 | ||
|
|
81120d4646 | ||
|
|
5c684b47b1 | ||
|
|
90f036816f | ||
|
|
ebdc385d1e | ||
|
|
323ee8dcc8 | ||
|
|
850418efe3 | ||
|
|
724aaca38e | ||
|
|
aac9d6290e | ||
|
|
68e1b78984 | ||
|
|
f7ae2025fa | ||
|
|
7f3e870cfe | ||
|
|
ed8cd12277 | ||
|
|
94c1303adc | ||
|
|
74410947ab | ||
|
|
c62d384b89 | ||
|
|
6522d3551f | ||
|
|
4591f2f6db | ||
|
|
0b4e8fc125 | ||
|
|
76355c0d94 | ||
|
|
3a9a97deda | ||
|
|
ff41610625 | ||
|
|
4cfb3a3121 | ||
|
|
44a8819a5b | ||
|
|
a5c6dfd299 | ||
|
|
efaca26eda | ||
|
|
f4a8e239eb | ||
|
|
908be0e3ed | ||
|
|
e02e91db86 | ||
|
|
48f6db779e | ||
|
|
a90d2b032d | ||
|
|
8e971ae0d3 | ||
|
|
c702afa0ee | ||
|
|
593d90a40a | ||
|
|
34eb905590 | ||
|
|
383c35a114 | ||
|
|
e6cfbadd08 | ||
|
|
50a11f61f8 | ||
|
|
1939496f6b | ||
|
|
bc8350122d | ||
|
|
d85abade7d | ||
|
|
97e078d87b | ||
|
|
721091be1b | ||
|
|
ad027f80a5 | ||
|
|
84a7b26e2c |
2
.github/dco.yml
vendored
Normal file
2
.github/dco.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
require:
|
||||
members: false
|
||||
4
.github/workflows/dependency-review.yml
vendored
4
.github/workflows/dependency-review.yml
vendored
@@ -17,11 +17,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
|
||||
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@72eb03d02c7872a771aacd928f3123ac62ad6d3a # v4.3.3
|
||||
uses: actions/dependency-review-action@4081bf99e2866ebe428fc0477b69eb4fcda7220a # v4.4.0
|
||||
|
||||
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@@ -15,13 +15,6 @@ jobs:
|
||||
with:
|
||||
username: dockerpublicbot
|
||||
password: ${{ secrets.DOCKERPUBLICBOT_WRITE_PAT }}
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@31c86eb3b33c9b601a1f60f98dcbfd1d70f379b4 # v1.10.3
|
||||
with:
|
||||
app-id: ${{ vars.APP_ID }}
|
||||
private-key: ${{ secrets.DOCKER_READ_APP_PRIVATE_KEY }}
|
||||
repositories: "attest,attest-provider"
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
@@ -52,5 +45,3 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64 # todo figure out additional platforms for release
|
||||
attests: type=sbom,generator=docker/scout-sbom-indexer:1
|
||||
provenance: mode=max
|
||||
secrets: |
|
||||
GITHUB_TOKEN=${{ steps.app-token.outputs.token }}
|
||||
|
||||
83
.github/workflows/scorecards.yml
vendored
83
.github/workflows/scorecards.yml
vendored
@@ -1,83 +0,0 @@
|
||||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecard supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: "20 7 * * 2"
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results and get a badge (see publish_results below).
|
||||
id-token: write
|
||||
contents: read
|
||||
actions: read
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@31c86eb3b33c9b601a1f60f98dcbfd1d70f379b4 # v1.10.3
|
||||
with:
|
||||
app-id: ${{ vars.DOCKER_READ_APP_ID }}
|
||||
private-key: ${{ secrets.DOCKER_READ_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecards on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
|
||||
repo_token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
# Public repositories:
|
||||
# - Publish results to OpenSSF REST API for easy access by consumers
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories:
|
||||
# - `publish_results` will always be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
37
.github/workflows/workflow.yaml
vendored
37
.github/workflows/workflow.yaml
vendored
@@ -20,35 +20,21 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
|
||||
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@31c86eb3b33c9b601a1f60f98dcbfd1d70f379b4 # v1.10.3
|
||||
with:
|
||||
app-id: ${{ vars.DOCKER_READ_APP_ID }}
|
||||
private-key: ${{ secrets.DOCKER_READ_APP_PRIVATE_KEY }}
|
||||
repositories: "attest,attest-provider"
|
||||
|
||||
- name: Set up Go 1.22
|
||||
uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
with:
|
||||
go-version: 1.22
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Download dependencies
|
||||
run: |
|
||||
export GOPRIVATE="github.com/docker/attest"
|
||||
git config --global "url.https://x-access-token:${{ steps.app-token.outputs.token }}@github.com.insteadof" "https://github.com"
|
||||
go mod download
|
||||
|
||||
# source: https://github.com/golangci/golangci-lint-action
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6.0.1
|
||||
uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1
|
||||
with:
|
||||
version: v1.59
|
||||
|
||||
@@ -60,26 +46,18 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
|
||||
uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Set up Go 1.22
|
||||
uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
|
||||
with:
|
||||
go-version: 1.22
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@31c86eb3b33c9b601a1f60f98dcbfd1d70f379b4 # v1.10.3
|
||||
with:
|
||||
app-id: ${{ vars.DOCKER_READ_APP_ID }}
|
||||
private-key: ${{ secrets.DOCKER_READ_APP_PRIVATE_KEY }}
|
||||
repositories: "attest,attest-provider"
|
||||
|
||||
- name: Bootstrap e2e
|
||||
env:
|
||||
KIND_VERSION: 0.23.0
|
||||
@@ -110,11 +88,14 @@ jobs:
|
||||
- name: Build and install attest-provider
|
||||
run: |
|
||||
./scripts/generate-tls-cert.sh
|
||||
export GITHUB_TOKEN=${{ steps.app-token.outputs.token }}
|
||||
make docker-buildx kind-load-image
|
||||
helm install attest-provider charts/attest-provider \
|
||||
--set provider.tls.caBundle="$(cat certs/ca.crt | base64 | tr -d '\n\r')" \
|
||||
--set image="docker/attest-provider:dev" \
|
||||
--set tufRoot=staging \
|
||||
--set tufMetadataSource=https://docker.github.io/tuf-staging/metadata \
|
||||
--set tufTargetsSource=https://docker.github.io/tuf-staging/targets \
|
||||
--set parameters="mode=strict" \
|
||||
--namespace security \
|
||||
--wait --debug
|
||||
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@ certs/
|
||||
|
||||
# binary output
|
||||
bin/
|
||||
.vscode/
|
||||
|
||||
131
CODE-OF-CONDUCT.md
Normal file
131
CODE-OF-CONDUCT.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official email address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by submitting an [incident report](https://docs.google.com/forms/d/e/1FAIpQLScezna1ZXRPzC_phSDoPEF4c5nvw8yQW-vvtI8xHjv-BB9MOg/viewform?c=0&w=1).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
|
||||
at [https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
90
CONTRIBUTING.md
Normal file
90
CONTRIBUTING.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Contribute to attest-provider
|
||||
|
||||
This guide will help you to find out how to contribute.
|
||||
|
||||
This page contains information about reporting issues as well as some tips and guidelines useful to experienced open source contributors. Finally, make sure you read our [community guidelines](#community-guidelines) before you start participating.
|
||||
|
||||
## Topics
|
||||
|
||||
- [Contribute to attest-provider](#contribute-to-attest-provider)
|
||||
- [Topics](#topics)
|
||||
- [Reporting security issues](#reporting-security-issues)
|
||||
- [Reporting other issues](#reporting-other-issues)
|
||||
- [How to report a bug](#how-to-report-a-bug)
|
||||
- [Quick contribution tips and guidelines](#quick-contribution-tips-and-guidelines)
|
||||
- [Contribution flow](#contribution-flow)
|
||||
- [Format of the commit message](#format-of-the-commit-message)
|
||||
- [Code review process](#code-review-process)
|
||||
- [Tips for contributors](#tips-for-contributors)
|
||||
|
||||
## Reporting security issues
|
||||
|
||||
The attest-provider maintainers take security seriously. If you discover a security issue, please bring it to their attention right away!
|
||||
|
||||
Please **DO NOT** file a public issue, instead send your report privately to [security@docker.com](mailto:security@docker.com).
|
||||
|
||||
Security reports are greatly appreciated and we will publicly thank you for it, although we keep your name confidential if you request it. We also like to send gifts—if you're into schwag, make sure to let us know. We currently do not offer a paid security bounty program, but are not ruling it out in the future.
|
||||
|
||||
## Reporting other issues
|
||||
|
||||
A great way to contribute to the project is to send a detailed report when you encounter an issue. We always appreciate a well-written, thorough bug report, and will thank you for it!
|
||||
|
||||
Check that [our issue database](https://github.com/docker/attest-provider/issues) doesn't already include that problem or suggestion before submitting an issue. If you find a match, you can use the "subscribe" button to get notified on updates. Do *not* leave random "+1" or "I have this too" comments. Those comments can become annoying very quickly. Instead, use [GitHub reactions](https://docs.github.com/en/free-pro-team@latest/github/writing-on-github/using-emojis).
|
||||
|
||||
### How to report a bug
|
||||
|
||||
* **Use a clear and descriptive title** for the issue to identify the problem.
|
||||
* **Describe the exact steps which reproduce the problem** in as many details as possible. When listing steps, **don't just say what you did, but explain how you did it**.
|
||||
* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
|
||||
* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
|
||||
* **Explain which behavior you expected to see instead and why.**
|
||||
* **Include screenshots and animated GIFs** which show you following the described steps and clearly demonstrate the problem.
|
||||
* **If the problem is related to performance or memory**, include a [CPU profile capture](https://blog.golang.org/profiling-go-programs) with your report.
|
||||
* **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened.
|
||||
* **Include the version of attest-provider you are using**.
|
||||
* **Include the name and version of the OS you're using**.
|
||||
|
||||
## Quick contribution tips and guidelines
|
||||
|
||||
This section gives a brief overview of how to propose a change to attest-provider.
|
||||
|
||||
### Contribution flow
|
||||
|
||||
1. Fork the repository on GitHub.
|
||||
2. Create a topic branch from where you want to base your work.
|
||||
3. Make commits of logical units.
|
||||
4. Make sure your commit messages are in the proper format (see below).
|
||||
5. Push your changes to a topic branch in your fork of the repository.
|
||||
6. Submit a pull request to the original repository.
|
||||
|
||||
### Format of the commit message
|
||||
|
||||
We follow a rough convention for commit messages [borrowed from Angular](https://www.conventionalcommits.org/en/v1.0.0/).
|
||||
|
||||
- **feat**: A new feature
|
||||
- **fix**: A bug fix
|
||||
- **docs**: Documentation only changes
|
||||
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||
- **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||
- **perf**: A code change that improves performance
|
||||
- **test**: Adding missing or correcting existing tests
|
||||
- **chore**: Changes to the build process or auxiliary tools and libraries such as documentation generation
|
||||
|
||||
### Code review process
|
||||
|
||||
All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose.
|
||||
|
||||
### Tips for contributors
|
||||
|
||||
1. All code should be formatted with `gofmt -s`.
|
||||
2. All code should pass the default levels of [`golint`](https://github.com/golang/lint).
|
||||
3. All code should follow the guidelines covered in [Effective Go](http://golang.org/doc/effective_go.html) and [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
|
||||
4. Comment the code. Tell us the why, the history, and the context.
|
||||
5. Document _all_ public declarations and methods. Declare expectations, caveats, and anything else that may be important. If a type gets exported, having the comments already there will ensure it's ready.
|
||||
6. Variable name length should be proportional to its context and no longer. `noCommaALongVariableNameLikeThisIsNotMoreClearWhenASimpleCommentWouldDo`. In practice, short methods will have short variable names and globals will have longer names.
|
||||
7. No underscores in package names. If you need a compound name, step back, and re-examine why you need a compound name. If you still think you need a compound name, lose the underscore.
|
||||
8. No utils or helpers packages. If a function is not general enough to warrant its own package, it has not been written generally enough to be a part of a util package. Just leave it unexported and well-documented.
|
||||
9. All tests should run with `go test` and outside tooling should not be required. No, we don't need another unit testing framework.
|
||||
10. Even though we call these "rules" above, they are actually just guidelines. Since you've read all the rules, you now know that.
|
||||
|
||||
If you are having trouble getting into the mood of idiomatic Go, we recommend reading through [Effective Go](https://go.dev/doc/effective_go). The [Go Blog](https://go.dev/blog/) is also a great resource. Drinking the kool-aid is a lot easier than going thirsty.
|
||||
31
Dockerfile
31
Dockerfile
@@ -1,3 +1,16 @@
|
||||
# Copyright Docker attest-provider authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
ARG BUILDERIMAGE="golang:1.22"
|
||||
ARG BASEIMAGE="gcr.io/distroless/static:nonroot"
|
||||
|
||||
@@ -7,22 +20,12 @@ ENV CGO_ENABLED=0
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# --- This block can be removed when github.com/docker/attest is public
|
||||
ENV GOPRIVATE="github.com/docker/attest"
|
||||
RUN --mount=type=secret,id=GITHUB_TOKEN <<EOT
|
||||
set -e
|
||||
GITHUB_TOKEN=${GITHUB_TOKEN:-$(cat /run/secrets/GITHUB_TOKEN)}
|
||||
if [ -n "$GITHUB_TOKEN" ]; then
|
||||
echo "Setting GitHub access token"
|
||||
git config --global "url.https://x-access-token:${GITHUB_TOKEN}@github.com.insteadof" "https://github.com"
|
||||
fi
|
||||
EOT
|
||||
# ---
|
||||
ARG VERSION="dev"
|
||||
|
||||
RUN --mount=type=bind,source=.,target=/app \
|
||||
--mount=type=cache,target=$GOPATH/pkg/mod \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
go build -o /bin/attest main.go
|
||||
--mount=type=cache,target=$GOPATH/pkg/mod \
|
||||
--mount=type=cache,target=/root/.cache/go-build \
|
||||
go build -ldflags "-X main.version=$VERSION" -o /bin/attest main.go
|
||||
|
||||
FROM ${BASEIMAGE} AS production
|
||||
|
||||
|
||||
15
Makefile
15
Makefile
@@ -1,3 +1,16 @@
|
||||
# Copyright Docker attest-provider authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
REPOSITORY ?= docker/attest-provider
|
||||
IMG := $(REPOSITORY):dev
|
||||
|
||||
@@ -30,7 +43,7 @@ docker-buildx-builder:
|
||||
|
||||
.PHONY: docker-buildx
|
||||
docker-buildx: docker-buildx-builder
|
||||
docker buildx build --platform linux/amd64 --load -t ${IMG} . --secret=id=GITHUB_TOKEN
|
||||
docker buildx build --platform linux/amd64 --load -t ${IMG} .
|
||||
|
||||
.PHONY: kind-load-image
|
||||
kind-load-image:
|
||||
|
||||
15
NOTICE
Normal file
15
NOTICE
Normal file
@@ -0,0 +1,15 @@
|
||||
Docker attest-provider
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
This product includes software developed at Docker, Inc. (https://www.docker.com).
|
||||
|
||||
The following is courtesy of our legal counsel:
|
||||
|
||||
Use and transfer of Docker may be subject to certain restrictions by the
|
||||
United States and other governments.
|
||||
It is your responsibility to ensure that your use and/or transfer does not
|
||||
violate applicable laws.
|
||||
|
||||
For more information, please see https://www.bis.doc.gov
|
||||
|
||||
See also https://www.apache.org/dev/crypto.html and/or seek legal counsel.
|
||||
18
README.md
18
README.md
@@ -26,8 +26,10 @@ helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
|
||||
# Install the latest version of Gatekeeper with the external data feature enabled.
|
||||
helm install gatekeeper/gatekeeper \
|
||||
--set enableExternalData=true \
|
||||
--set emitAdmissionEvents=true \
|
||||
--set emitAuditEvents=true \
|
||||
--set validatingWebhookFailurePolicy=Fail \
|
||||
--set validatingWebhookTimeoutSeconds=30 \
|
||||
--set validatingWebhookTimeoutSeconds=10 \
|
||||
--set postInstall.probeWebhook.enabled=false \
|
||||
--set postInstall.labelNamespace.enabled=false \
|
||||
--name-template=gatekeeper \
|
||||
@@ -55,19 +57,11 @@ make docker-buildx
|
||||
# load the image into kind
|
||||
make kind-load-image
|
||||
|
||||
# Choose one of the following ways to deploy the external data provider:
|
||||
|
||||
# 1. client and server auth enabled (recommended)
|
||||
helm install attest-provider charts/external-data-provider \
|
||||
# deploy attest provider
|
||||
helm install attest-provider charts/attest-provider \
|
||||
--set provider.tls.caBundle="$(cat certs/ca.crt | base64 | tr -d '\n\r')" \
|
||||
--set image="docker/attest-provider:dev" \
|
||||
--namespace "${NAMESPACE:-gatekeeper-system}"
|
||||
|
||||
# 2. client auth disabled and server auth enabled
|
||||
helm install attest-provider charts/external-data-provider \
|
||||
--set clientCAFile="" \
|
||||
--set provider.tls.caBundle="$(cat certs/ca.crt | base64 | tr -d '\n\r')" \
|
||||
--namespace "${NAMESPACE:-gatekeeper-system}" \
|
||||
--create-namespace
|
||||
```
|
||||
|
||||
4. Install constraint template and constraint.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
apiVersion: v2
|
||||
description: A Helm chart for attest external data provider
|
||||
name: attest-provider
|
||||
version: 0.0.6
|
||||
version: 0.1.0
|
||||
home: https://github.com/docker/attest-provider
|
||||
sources:
|
||||
- https://github.com/docker/attest-provider.git
|
||||
appVersion: 0.0.6
|
||||
appVersion: 0.1.0
|
||||
@@ -0,0 +1,18 @@
|
||||
## Parameters
|
||||
|
||||
|Parameter|Description|Default|
|
||||
|:-|:-|:-|
|
||||
|image|provider image to run|`docker/attest-provider:0.0.8`|
|
||||
|certDir|mount path to use for TLS certificates|`/certs`|
|
||||
|clientCAFile|optional mount path for gatekeeper client certificate (mTLS)|`/tmp/gatekeeper/ca.crt`|
|
||||
|port|port for provider service|`8090`|
|
||||
|handlerTimeout|timeout in seconds for provider HTTP handler|`25`|
|
||||
|replicas|number of provider replicas in deployment|`1`|
|
||||
|serviceAccountName|name of service account to attach to provider pods|``|
|
||||
|tufRoot|name of embedded Docker TUF root to use for client (`dev`, `staging`, `prod`)|`prod`|
|
||||
|tufMetadataSource|URI for TUF metadata (registry or http source)|`registry-1.docker.io/docker/tuf-metadata`|
|
||||
|tufTargetsSource|URI for TUF targets (registry or http source)|`registry-1.docker.io/docker/tuf-targets`|
|
||||
|attestationStyle|lookup attestations from image index (`attached`) or `referrers`|`referrers`|
|
||||
|provider.timeout|timeout in seconds for gatekeeper external data request|`30`|
|
||||
|provider.tls.caBundle|base64 encoded CA cert for provider|`""`|
|
||||
|parameters|additional parameters to pass to the policy implementation|`""`|
|
||||
|
||||
3
charts/attest-provider/templates/_helpers.tpl
Normal file
3
charts/attest-provider/templates/_helpers.tpl
Normal file
@@ -0,0 +1,3 @@
|
||||
{{- define "attest-provider.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
@@ -12,7 +12,12 @@ spec:
|
||||
metadata:
|
||||
labels:
|
||||
run: attest-provider
|
||||
app: '{{ template "attest-provider.name" . }}'
|
||||
chart: '{{ template "attest-provider.name" . }}'
|
||||
spec:
|
||||
{{- if .Values.serviceAccountName }}
|
||||
serviceAccountName: {{ .Values.serviceAccountName }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- image: {{ .Values.image }}
|
||||
imagePullPolicy: IfNotPresent
|
||||
@@ -28,6 +33,12 @@ spec:
|
||||
{{- if .Values.tufRoot }}
|
||||
- --tuf-root={{ .Values.tufRoot }}
|
||||
{{- end }}
|
||||
{{- if .Values.tufChannel }}
|
||||
- --tuf-channel={{ .Values.tufChannel }}
|
||||
{{- end }}
|
||||
{{- if .Values.handlerTimeout }}
|
||||
- --handler-timeout={{ .Values.handlerTimeout }}
|
||||
{{- end }}
|
||||
{{- if .Values.tufMetadataSource }}
|
||||
- --tuf-metadata-source={{ .Values.tufMetadataSource }}
|
||||
{{- end }}
|
||||
@@ -46,6 +57,9 @@ spec:
|
||||
{{- if .Values.referrersRepo }}
|
||||
- --referrers-source={{ .Values.referrersRepo }}
|
||||
{{- end }}
|
||||
{{- if .Values.parameters }}
|
||||
- --parameters={{ .Values.parameters }}
|
||||
{{- end }}
|
||||
|
||||
ports:
|
||||
- containerPort: {{ .Values.port }}
|
||||
@@ -68,6 +82,11 @@ spec:
|
||||
mountPath: {{ .Values.certDir }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: {{ .Values.port }}
|
||||
scheme: HTTPS
|
||||
restartPolicy: Always
|
||||
nodeSelector:
|
||||
kubernetes.io/os: linux
|
||||
|
||||
@@ -1,20 +1,32 @@
|
||||
image: "docker/attest-provider:0.0.6@sha256:1403ff1d17ffb9d330e90817ed05d080dec2bd4c9f7e611be07788111040342f"
|
||||
image: "docker/attest-provider:0.1.0@sha256:b401274d424223696dc7291c1845ebc2f34e77e43ab61d206ed87dbe6d4cbe52"
|
||||
|
||||
certDir: /certs
|
||||
clientCAFile: /tmp/gatekeeper/ca.crt
|
||||
port: 8090
|
||||
handlerTimeout: 25
|
||||
replicas: 1
|
||||
|
||||
# uncomment these lines to use the dev TUF root
|
||||
# uncomment these lines to use other TUF root environments
|
||||
# tufRoot: dev
|
||||
# tufMetadataSource: https://docker.github.io/tuf-dev/metadata
|
||||
# tufTargetsSource: https://docker.github.io/tuf-dev/targets
|
||||
#
|
||||
# tufRoot: staging
|
||||
# tufMetadataSource: registry-1.docker.io/docker/tuf-metadata-staging
|
||||
# tufTargetsSource: registry-1.docker.io/docker/tuf-targets-staging
|
||||
|
||||
tufMetadataSource: https://docker.github.io/tuf-staging/metadata
|
||||
tufTargetsSource: https://docker.github.io/tuf-staging/targets
|
||||
tufRoot: prod
|
||||
tufChannel: ""
|
||||
tufMetadataSource: registry-1.docker.io/docker/tuf-metadata
|
||||
tufTargetsSource: registry-1.docker.io/docker/tuf-targets
|
||||
|
||||
attestationStyle: referrers
|
||||
|
||||
# parameters for the the policy implementation
|
||||
# e.g. parameters: "mode=strict"
|
||||
|
||||
parameters: ""
|
||||
|
||||
provider:
|
||||
timeout: 30
|
||||
tls:
|
||||
|
||||
171
go.mod
171
go.mod
@@ -1,60 +1,81 @@
|
||||
module github.com/docker/attest-provider
|
||||
|
||||
go 1.22.1
|
||||
go 1.22.8
|
||||
|
||||
require (
|
||||
github.com/docker/attest v0.1.6
|
||||
github.com/google/go-containerregistry v0.19.2
|
||||
github.com/docker/attest v0.6.8
|
||||
github.com/google/go-containerregistry v0.20.2
|
||||
github.com/in-toto/in-toto-golang v0.9.0
|
||||
github.com/open-policy-agent/frameworks/constraint v0.0.0-20221214024800-b745745c4118
|
||||
k8s.io/klog/v2 v2.120.1
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
)
|
||||
|
||||
// fork of a fork (in case it goes away) with changes to support ArtifactType (https://github.com/google/go-containerregistry/pull/1931)
|
||||
replace github.com/google/go-containerregistry => github.com/kipz/go-containerregistry v0.0.0-20240722163910-ebe90246535d
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.25.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.12.3 // indirect
|
||||
cloud.google.com/go v0.116.0 // indirect
|
||||
cloud.google.com/go/auth v0.9.8 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.5.2 // indirect
|
||||
cloud.google.com/go/iam v1.2.1 // indirect
|
||||
cloud.google.com/go/kms v1.20.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.1 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.12.6 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
github.com/agnivade/levenshtein v1.1.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.0.0 // indirect
|
||||
github.com/agnivade/levenshtein v1.2.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.30.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.27.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.41 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.29.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.24.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.34.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.21.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.25.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.29.1 // indirect
|
||||
github.com/aws/smithy-go v1.20.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/kms v1.37.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 // indirect
|
||||
github.com/aws/smithy-go v1.22.0 // indirect
|
||||
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/containerd/containerd v1.7.18 // indirect
|
||||
github.com/containerd/errdefs v0.1.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.8 // indirect
|
||||
github.com/containerd/containerd v1.7.22 // indirect
|
||||
github.com/containerd/containerd/v2 v2.0.0-rc.5 // indirect
|
||||
github.com/containerd/errdefs v0.2.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
|
||||
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/cli v26.1.3+incompatible // indirect
|
||||
github.com/docker-library/bashbrew v0.1.12 // indirect
|
||||
github.com/docker/cli v27.1.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker v26.1.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.8.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/go-chi/chi v4.1.2+incompatible // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.12.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
@@ -69,96 +90,120 @@ require (
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/certificate-transparency-go v1.1.8 // indirect
|
||||
github.com/google/certificate-transparency-go v1.2.1 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.6 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0 // indirect
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/letsencrypt/boulder v0.0.0-20240613153800-a69ba997609e // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.17.10 // indirect
|
||||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/open-policy-agent/opa v0.65.0 // indirect
|
||||
github.com/open-policy-agent/opa v0.69.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/package-url/packageurl-go v0.1.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||
github.com/prometheus/client_golang v1.20.4 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.53.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.0 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sassoftware/relic v7.2.1+incompatible // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/sigstore/cosign/v2 v2.2.4 // indirect
|
||||
github.com/sigstore/cosign/v2 v2.4.1 // indirect
|
||||
github.com/sigstore/protobuf-specs v0.3.2 // indirect
|
||||
github.com/sigstore/rekor v1.3.6 // indirect
|
||||
github.com/sigstore/sigstore v1.8.3 // indirect
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.5 // indirect
|
||||
github.com/sigstore/sigstore v1.8.10 // indirect
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10 // indirect
|
||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10 // indirect
|
||||
github.com/sigstore/timestamp-authority v1.2.2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/cobra v1.8.0 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/spf13/viper v1.19.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
|
||||
github.com/theupdateframework/go-tuf v0.7.0 // indirect
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240504210453-5a634eb214ae // indirect
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.2 // indirect
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/transparency-dev/merkle v0.0.2 // indirect
|
||||
github.com/vbatts/tar-split v0.11.5 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/yashtewari/glob-intersection v0.2.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.15.0 // indirect
|
||||
go.opentelemetry.io/otel v1.27.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.27.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.27.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.27.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect
|
||||
go.opentelemetry.io/otel v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.30.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.30.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/oauth2 v0.19.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/term v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
google.golang.org/api v0.202.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/grpc v1.67.1 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.28.3 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
k8s.io/apimachinery v0.31.1 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
pault.ag/go/debian v0.12.0 // indirect
|
||||
pault.ag/go/topsort v0.1.1 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "76d0a7e1ff8617ce99627d0fa5c9809f2c0f0d52e0bf65c7b84c031608d25221",
|
||||
"sig": "3065023000f7d0a866576e94eaabc173b9233d4c8fcfa495527088f9022dff5a553f7a457da1015a6d0fc714f84848ec627387360231009fa70b2eebbe15241a2ec9b96a094ebd28661e30b8c3d1eab8d694df2b340bda511c489393630c9a9dacde42c99e9fa1"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "root",
|
||||
"consistent_snapshot": true,
|
||||
"expires": "2034-05-29T20:14:11Z",
|
||||
"keys": {
|
||||
"76d0a7e1ff8617ce99627d0fa5c9809f2c0f0d52e0bf65c7b84c031608d25221": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3+asmp2GD6UijwWvMezwVG/BwFLuQa3o\nT6eRxFvkILGpVDbZ92ZYWidHl9LZ/eJUjhIjuVEkNVKoenw5KjKl8veP3MthZrQA\nSkYytOIwkidZo9Rk2dczbDcFSJvLGsmd\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp384",
|
||||
"x-tuf-on-ci-keyowner": "@mrjoelkamp"
|
||||
},
|
||||
"bdd1703ecbde8812614b112a6551d58de3ad681048fd90fca2a3e491edd8afe5": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgDpP6O0sEt2R+l84WlfmqPBsFSby\nxJsJ6YmeUVgDk/wk9++8IAR6YBYewaKye56gMnIYjTFbyOI8WomA2NQFBw==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-online-uri": "awskms:arn:aws:kms:us-east-1:175142243308:key/fbd8dab6-5677-4b57-87e6-8369c45b3b61"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"root": {
|
||||
"keyids": [
|
||||
"76d0a7e1ff8617ce99627d0fa5c9809f2c0f0d52e0bf65c7b84c031608d25221"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"snapshot": {
|
||||
"keyids": [
|
||||
"bdd1703ecbde8812614b112a6551d58de3ad681048fd90fca2a3e491edd8afe5"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
},
|
||||
"targets": {
|
||||
"keyids": [
|
||||
"76d0a7e1ff8617ce99627d0fa5c9809f2c0f0d52e0bf65c7b84c031608d25221"
|
||||
],
|
||||
"threshold": 1
|
||||
},
|
||||
"timestamp": {
|
||||
"keyids": [
|
||||
"bdd1703ecbde8812614b112a6551d58de3ad681048fd90fca2a3e491edd8afe5"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 1,
|
||||
"x-tuf-on-ci-expiry-period": 3650,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "3da0404c531197e1e04622fb6ebcfe67ca462966c16115f856e8bba059b5f1de",
|
||||
"sig": "30450221008b9de747c24c07586cddf0aa25ecb37dbe9ce4f8cf2d5316fd7a470d42c803db0220715270e40c79b0b4af9858db44b10cec1a2f14ca5c217b1f1f6835f3a1ff843c"
|
||||
},
|
||||
{
|
||||
"keyid": "e642e70171046d6d97efdea76792c373d863c55c054c4287c999c62c6011120f",
|
||||
"sig": "3046022100c087742a7d10869163be844e4453566af461604cee99ab42560cef3136009cd4022100bedab954a32a693a9da63c2050a8cf4a2bd45e96daf586e489ad0fdd71ada2fd"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "root",
|
||||
"consistent_snapshot": true,
|
||||
"expires": "2024-11-15T17:56:20Z",
|
||||
"keys": {
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEgDpP6O0sEt2R+l84WlfmqPBsFSby\nxJsJ6YmeUVgDk/wk9++8IAR6YBYewaKye56gMnIYjTFbyOI8WomA2NQFBw==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-online-uri": "awskms:arn:aws:kms:us-east-1:175142243308:key/fbd8dab6-5677-4b57-87e6-8369c45b3b61"
|
||||
},
|
||||
"3da0404c531197e1e04622fb6ebcfe67ca462966c16115f856e8bba059b5f1de": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEERet/8hs3WHIXyOXNzhLpTOz6DBx\n7zzHnenJgV/TB0dRMAx6j9UVRvlEkh5OcYuktNeqnLpHce1rLjLjpiRPVg==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-keyowner": "@jonnystoten"
|
||||
},
|
||||
"e642e70171046d6d97efdea76792c373d863c55c054c4287c999c62c6011120f": {
|
||||
"keytype": "ecdsa",
|
||||
"keyval": {
|
||||
"public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMtH9o0x/EHc/Rzoco4RyqmR7UwA\n0sHROw/79CMdbPh3/egmMxci3N+dJl6Re/cNkqR9eQy7joULS2K9Oxgxww==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"scheme": "ecdsa-sha2-nistp256",
|
||||
"x-tuf-on-ci-keyowner": "@mrjoelkamp"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"root": {
|
||||
"keyids": [
|
||||
"3da0404c531197e1e04622fb6ebcfe67ca462966c16115f856e8bba059b5f1de",
|
||||
"e642e70171046d6d97efdea76792c373d863c55c054c4287c999c62c6011120f"
|
||||
],
|
||||
"threshold": 2
|
||||
},
|
||||
"snapshot": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 365,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
},
|
||||
"targets": {
|
||||
"keyids": [
|
||||
"3da0404c531197e1e04622fb6ebcfe67ca462966c16115f856e8bba059b5f1de",
|
||||
"e642e70171046d6d97efdea76792c373d863c55c054c4287c999c62c6011120f"
|
||||
],
|
||||
"threshold": 2
|
||||
},
|
||||
"timestamp": {
|
||||
"keyids": [
|
||||
"198f00ff96ea7cbfa7eac480cc9bfc43ce13bb434b901011ab777856533997d3"
|
||||
],
|
||||
"threshold": 1,
|
||||
"x-tuf-on-ci-expiry-period": 2,
|
||||
"x-tuf-on-ci-signing-period": 1
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0.31",
|
||||
"version": 1,
|
||||
"x-tuf-on-ci-expiry-period": 365,
|
||||
"x-tuf-on-ci-signing-period": 60
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package embed
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed embedded-roots/1.root-dev.json
|
||||
var DevRoot []byte
|
||||
|
||||
//go:embed embedded-roots/1.root-staging.json
|
||||
var StagingRoot []byte
|
||||
|
||||
var DefaultRoot = StagingRoot
|
||||
87
main.go
87
main.go
@@ -1,23 +1,42 @@
|
||||
/*
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/attest-provider/pkg/handler"
|
||||
"github.com/docker/attest-provider/pkg/utils"
|
||||
"github.com/docker/attest/useragent"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
handlerTimeout = 15 * time.Second
|
||||
readHeaderTimeout = 1 * time.Second
|
||||
)
|
||||
|
||||
@@ -29,11 +48,13 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
certDir string
|
||||
clientCAFile string
|
||||
port int
|
||||
certDir string
|
||||
clientCAFile string
|
||||
port int
|
||||
handlerTimeoutSeconds int
|
||||
|
||||
tufRoot string
|
||||
tufChannel string
|
||||
tufoutputPath string
|
||||
metadataURL string
|
||||
targetsURL string
|
||||
@@ -43,32 +64,54 @@ var (
|
||||
|
||||
attestationStyle string
|
||||
referrersRepo string
|
||||
parameters = make(nameValuePairs)
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMetadataURL = "registry-1.docker.io/docker/tuf-metadata:latest"
|
||||
defaultTargetsURL = "registry-1.docker.io/docker/tuf-targets"
|
||||
defaultTUFChannel = ""
|
||||
)
|
||||
|
||||
var (
|
||||
defaultTUFOutputPath = filepath.Join("/tuf_temp", ".docker", "tuf")
|
||||
defaultPolicyCacheDir = filepath.Join("/tuf_temp", ".docker", "policy")
|
||||
version = ""
|
||||
)
|
||||
|
||||
type nameValuePairs map[string]string
|
||||
|
||||
func (nvp nameValuePairs) String() string {
|
||||
return fmt.Sprintf("%v", map[string]string(nvp))
|
||||
}
|
||||
|
||||
func (nvp nameValuePairs) Set(value string) error {
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(value, ",")
|
||||
for _, part := range parts {
|
||||
kv := strings.Split(part, "=")
|
||||
if len(kv) != 2 {
|
||||
return fmt.Errorf("invalid format, expected name=value")
|
||||
}
|
||||
nvp[kv[0]] = kv[1]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var timeoutError = string(utils.GatekeeperError("operation timed out"))
|
||||
|
||||
func init() {
|
||||
// using initFlags to initialize the flags (standard init is a pain for testing).
|
||||
func initFlags() {
|
||||
klog.InitFlags(nil)
|
||||
flag.StringVar(&certDir, "cert-dir", "", "path to directory containing TLS certificates")
|
||||
flag.StringVar(&clientCAFile, "client-ca-file", "", "path to client CA certificate")
|
||||
flag.IntVar(&port, "port", defaultPort, "Port for the server to listen on")
|
||||
flag.StringVar(&tufRoot, "tuf-root", "staging", "specify embedded tuf root [dev, staging], default [staging]")
|
||||
|
||||
if tufRoot != "dev" && tufRoot != "staging" {
|
||||
klog.Errorf("invalid tuf root: %s", tufRoot)
|
||||
os.Exit(1)
|
||||
}
|
||||
flag.IntVar(&handlerTimeoutSeconds, "handler-timeout", 25, "timeout for handler in seconds")
|
||||
|
||||
flag.StringVar(&tufRoot, "tuf-root", "prod", "specify embedded tuf root [dev, staging, prod], default [prod]")
|
||||
flag.StringVar(&tufChannel, "tuf-channel", defaultTUFChannel, "release channel [prod, testing], default [prod]")
|
||||
flag.StringVar(&metadataURL, "tuf-metadata-source", defaultMetadataURL, "source (URL or repo) for TUF metadata")
|
||||
flag.StringVar(&targetsURL, "tuf-targets-source", defaultTargetsURL, "source (URL or repo) for TUF targets")
|
||||
flag.StringVar(&tufoutputPath, "tuf-output-path", defaultTUFOutputPath, "local dir to store TUF repo metadata")
|
||||
@@ -79,14 +122,25 @@ func init() {
|
||||
flag.StringVar(&attestationStyle, "attestation-style", "referrers", "attestation style [referrers, attached]")
|
||||
flag.StringVar(&referrersRepo, "referrers-source", "", "repo from which to fetch Referrers for attestation lookup")
|
||||
|
||||
flag.Var(¶meters, "parameters", "policy parameters in name=value,name1,value1 format")
|
||||
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
initFlags()
|
||||
mux := http.NewServeMux()
|
||||
handlerTimeout := time.Duration(handlerTimeoutSeconds) * time.Second
|
||||
|
||||
validateHandler, err := handler.NewValidateHandler(&handler.ValidateHandlerOptions{
|
||||
ctx := useragent.Set(context.Background(), "attest-provider/"+version+" (docker)")
|
||||
|
||||
if tufChannel == "prod" {
|
||||
tufChannel = ""
|
||||
}
|
||||
|
||||
validateHandler, err := handler.NewValidateHandler(ctx, &handler.ValidateHandlerOptions{
|
||||
TUFRoot: tufRoot,
|
||||
TUFChannel: tufChannel,
|
||||
TUFOutputPath: tufoutputPath,
|
||||
TUFMetadataURL: metadataURL,
|
||||
TUFTargetsURL: targetsURL,
|
||||
@@ -94,6 +148,7 @@ func main() {
|
||||
PolicyCacheDir: policyCacheDir,
|
||||
AttestationStyle: attestationStyle,
|
||||
ReferrersRepo: referrersRepo,
|
||||
Parameters: parameters,
|
||||
})
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "unable to create validate handler")
|
||||
@@ -108,11 +163,17 @@ func main() {
|
||||
|
||||
mux.Handle("POST /validate", http.TimeoutHandler(validateHandler, handlerTimeout, timeoutError))
|
||||
mux.Handle("POST /mutate", http.TimeoutHandler(mutateHandler, handlerTimeout, timeoutError))
|
||||
mux.Handle("GET /ready", http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}))
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", port),
|
||||
Handler: mux,
|
||||
ReadHeaderTimeout: readHeaderTimeout,
|
||||
BaseContext: func(_ net.Listener) context.Context {
|
||||
return ctx
|
||||
},
|
||||
}
|
||||
|
||||
config := &tls.Config{
|
||||
@@ -130,7 +191,7 @@ func main() {
|
||||
clientCAs.AppendCertsFromPEM(caCert)
|
||||
|
||||
config.ClientCAs = clientCAs
|
||||
config.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
config.ClientAuth = tls.VerifyClientCertIfGiven
|
||||
server.TLSConfig = config
|
||||
}
|
||||
|
||||
|
||||
41
main_test.go
Normal file
41
main_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_nameValuePairs_Set(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
nvp nameValuePairs
|
||||
wantErr bool
|
||||
input string
|
||||
}{
|
||||
{name: "no value", nvp: nameValuePairs{}, input: "key=value", wantErr: false},
|
||||
{name: "invalid", nvp: nameValuePairs{}, input: "keyvalue", wantErr: true},
|
||||
{name: "empty", nvp: nameValuePairs{}, input: "", wantErr: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := tt.nvp.Set(tt.input); (err != nil) != tt.wantErr {
|
||||
t.Errorf("nameValuePairs.Set() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
@@ -8,7 +24,7 @@ import (
|
||||
"runtime/debug"
|
||||
|
||||
"github.com/docker/attest-provider/pkg/utils"
|
||||
"github.com/docker/attest/pkg/oci"
|
||||
"github.com/docker/attest/oci"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"github.com/open-policy-agent/frameworks/constraint/pkg/externaldata"
|
||||
|
||||
@@ -1,33 +1,50 @@
|
||||
/*
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
|
||||
"github.com/docker/attest-provider/internal/embed"
|
||||
"github.com/docker/attest"
|
||||
"github.com/docker/attest-provider/pkg/utils"
|
||||
"github.com/docker/attest/pkg/attest"
|
||||
"github.com/docker/attest/pkg/config"
|
||||
"github.com/docker/attest/pkg/oci"
|
||||
"github.com/docker/attest/pkg/policy"
|
||||
"github.com/docker/attest/pkg/tuf"
|
||||
"github.com/docker/attest/mapping"
|
||||
"github.com/docker/attest/oci"
|
||||
"github.com/docker/attest/policy"
|
||||
"github.com/docker/attest/tuf"
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
"github.com/open-policy-agent/frameworks/constraint/pkg/externaldata"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
type ValidationResult struct {
|
||||
Outcome attest.Outcome `json:"outcome"`
|
||||
Input *policy.PolicyInput `json:"input"`
|
||||
VSA *intoto.Statement `json:"vsa"`
|
||||
Violations []policy.Violation `json:"violations"`
|
||||
Outcome attest.Outcome `json:"outcome"`
|
||||
Input *policy.Input `json:"input"`
|
||||
VSA *intoto.Statement `json:"vsa"`
|
||||
Violations []policy.Violation `json:"violations"`
|
||||
}
|
||||
|
||||
type ValidateHandlerOptions struct {
|
||||
TUFRoot string
|
||||
TUFChannel string
|
||||
TUFOutputPath string
|
||||
TUFMetadataURL string
|
||||
TUFTargetsURL string
|
||||
@@ -37,21 +54,25 @@ type ValidateHandlerOptions struct {
|
||||
|
||||
AttestationStyle string
|
||||
ReferrersRepo string
|
||||
Parameters map[string]string
|
||||
}
|
||||
|
||||
type validateHandler struct {
|
||||
opts *ValidateHandlerOptions
|
||||
}
|
||||
|
||||
func NewValidateHandler(opts *ValidateHandlerOptions) (http.Handler, error) {
|
||||
func NewValidateHandler(ctx context.Context, opts *ValidateHandlerOptions) (http.Handler, error) {
|
||||
handler := &validateHandler{opts: opts}
|
||||
|
||||
// a TUF client can only be used once, so we need to create a new one for each request.
|
||||
// we create this one up front to ensure that the TUF root is valid and to pre-load the metadata.
|
||||
// TODO: this pre-loading works for the root, targets, snapshot, and timestamp roles, but not for delegated roles.
|
||||
_, err := handler.createTUFClient()
|
||||
_, err := handler.newVerifier(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// if this failed, don't return an error, just log it and continue
|
||||
// this prevents the server from getting into a crash loop if the TUF repo is down or broken,
|
||||
// and we can still recover if the TUF repo comes back up.
|
||||
klog.ErrorS(err, "failed to initialize TUF client")
|
||||
}
|
||||
|
||||
klog.Infof("validate handler initialized with %s TUF root", opts.TUFRoot)
|
||||
@@ -59,17 +80,33 @@ func NewValidateHandler(opts *ValidateHandlerOptions) (http.Handler, error) {
|
||||
return handler, nil
|
||||
}
|
||||
|
||||
func (h *validateHandler) createTUFClient() (*tuf.TufClient, error) {
|
||||
var rootBytes []byte
|
||||
switch h.opts.TUFRoot {
|
||||
case "dev":
|
||||
rootBytes = embed.DevRoot
|
||||
case "staging":
|
||||
rootBytes = embed.StagingRoot
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid tuf root: %s", h.opts.TUFRoot)
|
||||
func (h *validateHandler) newVerifier(ctx context.Context) (*attest.ImageVerifier, error) {
|
||||
root, err := tuf.GetEmbeddedRoot(h.opts.TUFRoot)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tuf.NewTufClient(rootBytes, h.opts.TUFOutputPath, h.opts.TUFMetadataURL, h.opts.TUFTargetsURL, tuf.NewVersionChecker())
|
||||
|
||||
policyOpts := &policy.Options{
|
||||
TUFClientOptions: &tuf.ClientOptions{
|
||||
InitialRoot: root.Data,
|
||||
LocalStorageDir: h.opts.TUFOutputPath,
|
||||
MetadataSource: h.opts.TUFMetadataURL,
|
||||
TargetsSource: h.opts.TUFTargetsURL,
|
||||
PathPrefix: h.opts.TUFChannel,
|
||||
VersionChecker: tuf.NewDefaultVersionChecker(),
|
||||
},
|
||||
LocalTargetsDir: h.opts.PolicyCacheDir,
|
||||
LocalPolicyDir: h.opts.PolicyDir,
|
||||
AttestationStyle: mapping.AttestationStyle(h.opts.AttestationStyle),
|
||||
ReferrersRepo: h.opts.ReferrersRepo,
|
||||
Debug: true,
|
||||
Parameters: h.opts.Parameters,
|
||||
}
|
||||
verifier, err := attest.NewImageVerifier(ctx, policyOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return verifier, nil
|
||||
}
|
||||
|
||||
func (h *validateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
@@ -81,8 +118,6 @@ func (h *validateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
}()
|
||||
|
||||
ctx := req.Context()
|
||||
debug := true
|
||||
ctx = policy.WithPolicyEvaluator(ctx, policy.NewRegoEvaluator(debug))
|
||||
|
||||
// read request body
|
||||
requestBody, err := io.ReadAll(req.Body)
|
||||
@@ -101,20 +136,13 @@ func (h *validateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tufClient, err := h.createTUFClient()
|
||||
// create a new verifier for each request
|
||||
attest, err := h.newVerifier(ctx)
|
||||
if err != nil {
|
||||
utils.SendResponse(nil, fmt.Sprintf("unable to create TUF client: %v", err), w)
|
||||
utils.SendResponse(nil, fmt.Sprintf("unable to create verifier: %v", err), w)
|
||||
return
|
||||
}
|
||||
|
||||
policyOpts := &policy.PolicyOptions{
|
||||
TufClient: tufClient,
|
||||
LocalTargetsDir: h.opts.PolicyCacheDir,
|
||||
LocalPolicyDir: h.opts.PolicyDir,
|
||||
AttestationStyle: config.AttestationStyle(h.opts.AttestationStyle),
|
||||
ReferrersRepo: h.opts.ReferrersRepo,
|
||||
}
|
||||
|
||||
results := make([]externaldata.Item, 0)
|
||||
for _, key := range providerRequest.Request.Keys {
|
||||
platform := "linux/amd64"
|
||||
@@ -124,7 +152,7 @@ func (h *validateHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := attest.Verify(ctx, src, policyOpts)
|
||||
result, err := attest.Verify(ctx, src)
|
||||
if err != nil {
|
||||
utils.SendResponse(nil, err.Error(), w)
|
||||
return
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright Docker attest-provider authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
13
template/bash.txt
Normal file
13
template/bash.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright Docker attest-provider authors
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
13
template/dockerfile.txt
Normal file
13
template/dockerfile.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright Docker attest-provider authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
16
template/go.txt
Normal file
16
template/go.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
Copyright Docker attest-provider authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
13
template/makefile.txt
Normal file
13
template/makefile.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright Docker attest-provider authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
Reference in New Issue
Block a user