├── cmd ├── run_test.go ├── version.go ├── list.go ├── run.go ├── generate-plugin.go └── root.go ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.yml │ └── bug_report.yml ├── workflows │ ├── pr-title.yml │ ├── auto-labeler.yml │ ├── lint.yml │ ├── post-merge.yml │ ├── osps-security-assessment.yml │ ├── release.yml │ └── ci.yml ├── dependabot.yml ├── release-drafter.yml └── security-insights.yml ├── Dockerfile ├── .gitignore ├── main.go ├── main_test.go ├── .goreleaser.yaml ├── Makefile ├── go.mod ├── install.sh ├── README.md ├── LICENSE ├── go.sum └── test └── data └── OSPS_Baseline_AC_2025_02.yaml /cmd/run_test.go: -------------------------------------------------------------------------------- 1 | package cmd_test 2 | 3 | // 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # All PRs in this repository will be blocked until they 2 | # have been approved by the respective code owner 3 | 4 | * @privateerproj/oss 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | 3 | contact_links: 4 | - name: Ask a question by filing an issue 5 | url: https://github.com/privateerproj/privateer/issues/new/choose 6 | about: Ask a question by filing an issue 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.4-alpine3.21 AS build 2 | 3 | WORKDIR /app 4 | 5 | COPY . . 6 | 7 | RUN apk add --no-cache make git && \ 8 | go mod tidy && \ 9 | make build 10 | 11 | FROM alpine:3.21 12 | 13 | WORKDIR /app 14 | 15 | COPY --from=build /app/privateer /app/privateer 16 | 17 | CMD ["/app/privateer", "--help"] 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VS Code 2 | .vscode 3 | __debug_bin 4 | 5 | # IntelliJ 6 | .idea 7 | 8 | # privateer 9 | privateer_output 10 | privateer 11 | privateer.exe 12 | privateer-darwin 13 | bin 14 | config* 15 | 16 | # Test 17 | coverage.out 18 | 19 | # OS 20 | .DS_Store 21 | dist/ 22 | 23 | test_output 24 | 25 | **/generated-plugin 26 | 27 | !.github/ISSUE_TEMPLATE/config.yml 28 | 29 | evaluation_results 30 | -------------------------------------------------------------------------------- /.github/workflows/pr-title.yml: -------------------------------------------------------------------------------- 1 | ## Reference: https://github.com/amannn/action-semantic-pull-request 2 | --- 3 | name: "Lint PR Title" 4 | on: 5 | # pull_request_target event is required for autolabeler to support all PRs including forks 6 | pull_request_target: 7 | types: [opened, reopened, edited, synchronize] 8 | jobs: 9 | lint_pr_title: 10 | permissions: 11 | contents: read 12 | pull-requests: read 13 | statuses: write 14 | uses: github/ospo-reusable-workflows/.github/workflows/pr-title.yaml@26eec20abba5ae806698592c79628f6906da372c 15 | secrets: 16 | github-token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/auto-labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Auto Labeler" 3 | on: 4 | # pull_request_target event is required for autolabeler to support all PRs including forks 5 | pull_request_target: 6 | types: [opened, reopened, edited, synchronize] 7 | permissions: 8 | contents: read 9 | jobs: 10 | auto_labeler: 11 | permissions: 12 | contents: read 13 | pull-requests: write 14 | uses: github/ospo-reusable-workflows/.github/workflows/auto-labeler.yaml@26eec20abba5ae806698592c79628f6906da372c 15 | with: 16 | config-name: release-drafter.yml 17 | secrets: 18 | github-token: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | pull-requests: read 12 | 13 | jobs: 14 | lint: 15 | name: lint 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v6 19 | with: 20 | persist-credentials: false 21 | - uses: actions/setup-go@v6 22 | with: 23 | go-version-file: go.mod 24 | - name: golangci-lint 25 | uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 26 | with: 27 | version: v2.4.0 28 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" 8 | commit-message: 9 | prefix: "chore(deps)" 10 | labels: ["go", "dependencies"] 11 | groups: 12 | dependencies: 13 | applies-to: version-updates 14 | update-types: 15 | - "minor" 16 | - "patch" 17 | - package-ecosystem: "github-actions" 18 | directory: "/" 19 | schedule: 20 | interval: "weekly" 21 | commit-message: 22 | prefix: "chore(deps)" 23 | labels: ["github_actions", "dependencies"] 24 | groups: 25 | dependencies: 26 | applies-to: version-updates 27 | update-types: 28 | - "minor" 29 | - "patch" 30 | -------------------------------------------------------------------------------- /.github/workflows/post-merge.yml: -------------------------------------------------------------------------------- 1 | name: Post merge to main 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | first_test_job: 9 | name: Find extra commits 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v6 14 | with: 15 | persist-credentials: false 16 | - id: Fetch_tags 17 | run: git fetch --prune --unshallow --tags 18 | - run: git describe --tags 19 | - id: set_output_tags 20 | run: | 21 | echo ::set-output name=extra_commits::$(git describe --tags) 22 | - name: Set Badge 23 | uses: RubbaBoy/BYOB@a4919104bc0ec7cfd7f113e42c405cc45246f2a4 24 | with: 25 | name: Version 26 | label: "Version" 27 | status: ${{ steps.set_output_tags.outputs.extra_commits }} 28 | color: CFC03A 29 | github_token: ${{ secrets.GITHUB_TOKEN }} 30 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/viper" 9 | ) 10 | 11 | // versionCmd represents the version command, which displays version information 12 | // about the Privateer build including version, commit hash, and build time. 13 | var versionCmd = &cobra.Command{ 14 | Use: "version", 15 | Short: "Display version details.", 16 | Long: `Display the version, git commit hash, and build timestamp of this Privateer build. Use the --verbose flag to see all details.`, 17 | Run: func(cmd *cobra.Command, args []string) { 18 | if viper.GetBool("verbose") { 19 | _, _ = fmt.Fprintf(writer, "Version:\t%s\n", buildVersion) 20 | _, _ = fmt.Fprintf(writer, "Commit:\t%s\n", buildGitCommitHash) 21 | _, _ = fmt.Fprintf(writer, "Build Time:\t%s\n", buildTime) 22 | err := writer.Flush() 23 | if err != nil { 24 | log.Printf("Error flushing writer: %v", err) 25 | } 26 | } else { 27 | fmt.Println(buildVersion) 28 | } 29 | }, 30 | } 31 | 32 | func init() { 33 | rootCmd.AddCommand(versionCmd) 34 | } 35 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Package main provides the entry point for the Privateer command-line tool. 2 | // Privateer is a security testing framework that executes plugins to perform 3 | // security evaluations and assessments. 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | 9 | "github.com/privateerproj/privateer/cmd" 10 | ) 11 | 12 | var ( 13 | // Version is the version string that will be replaced at build time by the associated tag. 14 | Version = "0.0.0" 15 | // VersionPostfix is a marker for the version such as "dev", "beta", "rc", etc. 16 | // This is appended to the version string if it is not empty. 17 | VersionPostfix = "dev" 18 | // GitCommitHash is the git commit hash at build time. 19 | GitCommitHash = "" 20 | // BuiltAt is the actual build datetime string. 21 | BuiltAt = "" 22 | ) 23 | 24 | // main is the entry point for the Privateer application. 25 | // It formats the version string with any postfix and executes the root command. 26 | func main() { 27 | if VersionPostfix != "" { 28 | Version = fmt.Sprintf("%s-%s", Version, VersionPostfix) 29 | } 30 | cmd.Execute(Version, GitCommitHash, BuiltAt) 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | description: Suggest an idea for this project 4 | labels: 5 | - enhancement 6 | body: 7 | - type: textarea 8 | attributes: 9 | label: Is your feature request related to a problem? 10 | description: A clear and concise description of what the problem is. Please describe. 11 | placeholder: | 12 | Ex. I'm always frustrated when [...] 13 | validations: 14 | required: false 15 | 16 | - type: textarea 17 | attributes: 18 | label: Describe the solution you'd like 19 | description: A clear and concise description of what you want to happen. 20 | validations: 21 | required: true 22 | 23 | - type: textarea 24 | attributes: 25 | label: Describe alternatives you've considered 26 | description: A clear and concise description of any alternative solutions or features you've considered. 27 | validations: 28 | required: false 29 | 30 | - type: textarea 31 | attributes: 32 | label: Additional context 33 | description: Add any other context or screenshots about the feature request here. 34 | validations: 35 | required: false 36 | -------------------------------------------------------------------------------- /.github/workflows/osps-security-assessment.yml: -------------------------------------------------------------------------------- 1 | name: OSPS Security Assessment 2 | 3 | on: 4 | schedule: 5 | # Run weekly on Mondays at 9 AM UTC 6 | - cron: "0 9 * * 1" 7 | workflow_dispatch: # Allow manual triggering 8 | 9 | jobs: 10 | osps-assessment: 11 | runs-on: ubuntu-latest 12 | name: OSPS Security Assessment 13 | 14 | permissions: 15 | contents: read 16 | security-events: write # Required for SARIF upload 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v6 21 | 22 | - name: Open Source Project Security Baseline Scanner 23 | uses: revanite-io/osps-baseline-action@v1.0.0 24 | with: 25 | owner: ${{ github.repository_owner }} 26 | repo: ${{ github.event.repository.name }} 27 | token: ${{ secrets.PRIVATEER_GITHUB_TOKEN }} 28 | catalog: "osps-baseline" 29 | upload-sarif: "true" 30 | 31 | - name: Upload Assessment Results 32 | if: always() 33 | uses: actions/upload-artifact@v6 34 | with: 35 | name: osps-assessment-results-${{ github.run_number }} 36 | path: evaluation_results/ 37 | retention-days: 30 38 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Release" 3 | on: 4 | workflow_dispatch: 5 | pull_request_target: 6 | types: [closed] 7 | branches: [main] 8 | jobs: 9 | release: 10 | permissions: 11 | contents: write 12 | pull-requests: read 13 | uses: github/ospo-reusable-workflows/.github/workflows/release.yaml@26eec20abba5ae806698592c79628f6906da372c 14 | with: 15 | publish: true 16 | release-config-name: release-drafter.yml 17 | secrets: 18 | github-token: ${{ secrets.GITHUB_TOKEN }} 19 | goreleaser: 20 | needs: release 21 | runs-on: ubuntu-latest 22 | permissions: 23 | contents: write 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v6 27 | with: 28 | fetch-depth: 0 29 | persist-credentials: false 30 | - name: Set up Go 31 | uses: actions/setup-go@v6 32 | with: 33 | go-version-file: go.mod 34 | - name: Run GoReleaser 35 | uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a 36 | with: 37 | distribution: goreleaser 38 | version: "~> v2" 39 | args: release --clean 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 42 | -------------------------------------------------------------------------------- /cmd/list.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/spf13/viper" 6 | 7 | "github.com/privateerproj/privateer-sdk/command" 8 | ) 9 | 10 | // listCmd represents the list command, which displays all installed plugins. 11 | var listCmd *cobra.Command 12 | 13 | func init() { 14 | // Create a wrapper command that gets the writer at runtime 15 | // This is necessary because writer is nil at package init time 16 | // and only gets initialized in persistentPreRun() 17 | listCmd = &cobra.Command{ 18 | Use: "list", 19 | Short: "Consult the Charts! List all plugins that have been installed.", 20 | Run: func(cmd *cobra.Command, args []string) { 21 | // Get the list command from SDK with the initialized writer 22 | // At this point, writer has been initialized by persistentPreRun() 23 | sdkListCmd := command.GetListCmd(writer) 24 | // Execute the SDK command's Run function 25 | sdkListCmd.Run(cmd, args) 26 | }, 27 | } 28 | 29 | // Add flags (matching the SDK command) 30 | listCmd.PersistentFlags().BoolP("all", "a", false, "Review the Fleet! List all plugins that have been installed or requested in the current config") 31 | _ = viper.BindPFlag("all", listCmd.PersistentFlags().Lookup("all")) 32 | 33 | rootCmd.AddCommand(listCmd) 34 | } 35 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_getVersion(t *testing.T) { 8 | // tests := []struct { 9 | // testName string 10 | // prerelase string 11 | // version string 12 | // expectedResult string 13 | // }{ 14 | // // Test cases 15 | // { 16 | // testName: "getVersion_WithDevPrelease_ShouldReturnVersionAndVersionPostfix", 17 | // prerelase: "dev", 18 | // version: "0.0.0", 19 | // expectedResult: "0.0.0-dev", 20 | // }, 21 | // { 22 | // testName: "getVersion_WithRCPrelease_ShouldReturnVersionAndVersionPostfix", 23 | // prerelase: "rc", 24 | // version: "0.0.1", 25 | // expectedResult: "0.0.1-rc", 26 | // }, 27 | // { 28 | // testName: "getVersion_WithoutPrelease_ShouldReturnVersionOnly", 29 | // prerelase: "", 30 | // version: "0.0.2", 31 | // expectedResult: "0.0.2", 32 | // }, 33 | // } 34 | // for _, tt := range tests { 35 | // t.Run(tt.testName, func(t *testing.T) { 36 | // Version = tt.version 37 | // VersionPostfix = tt.prerelase 38 | // printVersion() 39 | // if Version != tt.expectedResult { 40 | // t.Errorf("getVersion() = %v, expected %v", Version, tt.expectedResult) 41 | // } 42 | // }) 43 | // } 44 | } 45 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # This is an example .goreleaser.yml file with some sensible defaults. 2 | # Make sure to check the documentation at https://goreleaser.com 3 | 4 | # The lines below are called `modelines`. See `:help modeline` 5 | # Feel free to remove those if you don't want/need to use them. 6 | # yaml-language-server: $schema=https://goreleaser.com/static/schema.json 7 | # vim: set ts=2 sw=2 tw=0 fo=cnqoj 8 | 9 | version: 2 10 | 11 | before: 12 | hooks: 13 | - go mod tidy 14 | 15 | builds: 16 | - env: 17 | - CGO_ENABLED=0 18 | goos: 19 | - linux 20 | - windows 21 | - darwin 22 | 23 | archives: 24 | - formats: ["tar.gz"] 25 | # this name template makes the OS and Arch compatible with the results of `uname`. 26 | name_template: >- 27 | {{ .ProjectName }}_ 28 | {{- title .Os }}_ 29 | {{- if eq .Arch "amd64" }}x86_64 30 | {{- else if eq .Arch "386" }}i386 31 | {{- else }}{{ .Arch }}{{ end }} 32 | {{- if .Arm }}v{{ .Arm }}{{ end }} 33 | # use zip for windows archives 34 | format_overrides: 35 | - goos: windows 36 | formats: ["zip"] 37 | 38 | changelog: 39 | sort: asc 40 | filters: 41 | exclude: 42 | - "^docs:" 43 | - "^test:" 44 | 45 | release: 46 | prerelease: auto 47 | 48 | universal_binaries: 49 | - replace: true 50 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | description: Create a report to help us improve 4 | labels: 5 | - bug 6 | body: 7 | - type: textarea 8 | attributes: 9 | label: Version of privateer 10 | description: The version of privateer you're experiencing the bug on. 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | attributes: 16 | label: Describe the bug 17 | description: A clear and concise description of what the bug is. 18 | validations: 19 | required: true 20 | 21 | - type: textarea 22 | attributes: 23 | label: To Reproduce 24 | description: Steps to reproduce the behavior 25 | placeholder: | 26 | 1. Go to '...' 27 | 2. Click on '....' 28 | 3. Scroll down to '....' 29 | 4. See error 30 | validations: 31 | required: true 32 | 33 | - type: textarea 34 | attributes: 35 | label: Expected behavior 36 | description: A clear and concise description of what you expected to happen. 37 | validations: 38 | required: true 39 | 40 | - type: textarea 41 | attributes: 42 | label: Screenshots 43 | description: If applicable, add screenshots to help explain your problem. 44 | validations: 45 | required: false 46 | 47 | - type: textarea 48 | attributes: 49 | label: Additional context 50 | description: Add any other context about the problem here. 51 | validations: 52 | required: false 53 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name-template: "v$RESOLVED_VERSION" 3 | tag-template: "v$RESOLVED_VERSION" 4 | template: | 5 | # Changelog 6 | $CHANGES 7 | 8 | See details of [all code changes](https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION) since previous release 9 | 10 | categories: 11 | - title: "🚀 Features" 12 | labels: 13 | - "feature" 14 | - "enhancement" 15 | - title: "🐛 Bug Fixes" 16 | labels: 17 | - "fix" 18 | - "bugfix" 19 | - "bug" 20 | - title: "🧰 Maintenance" 21 | labels: 22 | - "infrastructure" 23 | - "automation" 24 | - "documentation" 25 | - "dependencies" 26 | - "maintenance" 27 | - "revert" 28 | - title: "🏎 Performance" 29 | label: "performance" 30 | change-template: "- $TITLE @$AUTHOR (#$NUMBER)" 31 | version-resolver: 32 | major: 33 | labels: 34 | - "breaking" 35 | minor: 36 | labels: 37 | - "feature" 38 | - "enhancement" 39 | patch: 40 | labels: 41 | - "fix" 42 | - "documentation" 43 | - "maintenance" 44 | default: patch 45 | autolabeler: 46 | - label: "automation" 47 | title: 48 | - "/^(build|ci|perf|refactor|test).*/i" 49 | - label: "enhancement" 50 | title: 51 | - "/^(style).*/i" 52 | - label: "documentation" 53 | title: 54 | - "/^(docs).*/i" 55 | - label: "feature" 56 | title: 57 | - "/^(feat).*/i" 58 | - label: "fix" 59 | title: 60 | - "/^(fix).*/i" 61 | - label: "infrastructure" 62 | title: 63 | - "/^(infrastructure).*/i" 64 | - label: "maintenance" 65 | title: 66 | - "/^(chore|maintenance).*/i" 67 | - label: "revert" 68 | title: 69 | - "/^(revert).*/i" 70 | -------------------------------------------------------------------------------- /cmd/run.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | 9 | "github.com/spf13/cobra" 10 | 11 | "github.com/privateerproj/privateer-sdk/command" 12 | ) 13 | 14 | // runCmd represents the run command, which executes all plugins specified in the configuration. 15 | var runCmd = &cobra.Command{ 16 | Use: "run", 17 | Short: "Run plugins that have been specified in the config.", 18 | Long: ` 19 | When everything is battoned down, it is time to run forth.`, 20 | Run: func(cmd *cobra.Command, args []string) { 21 | logger.Trace("run called") 22 | if len(args) > 0 { 23 | logger.Error(fmt.Sprintf( 24 | "Unknown args: %v", args)) 25 | } else { 26 | exitCode := Run() 27 | os.Exit(int(exitCode)) 28 | } 29 | }, 30 | } 31 | 32 | func init() { 33 | rootCmd.AddCommand(runCmd) 34 | } 35 | 36 | // Run executes all plugins with handling for the command line. 37 | // It sets up signal handlers for graceful shutdown and returns the exit code 38 | // from the plugin execution. 39 | // 40 | // Returns: 41 | // - exitCode: The exit code from the plugin execution (0 for success, non-zero for failure) 42 | func Run() (exitCode int) { 43 | // Setup for handling SIGTERM (Ctrl+C) 44 | setupCloseHandler() 45 | 46 | return command.Run(logger, command.GetPlugins) 47 | } 48 | 49 | // setupCloseHandler creates a signal listener on a new goroutine which will notify 50 | // the program if it receives an interrupt from the OS (SIGINT or SIGTERM). 51 | // When an interrupt is received, it logs an error message and exits with the 52 | // Aborted exit code. 53 | // 54 | // Reference: https://golangcode.com/handle-ctrl-c-exit-in-terminal/ 55 | func setupCloseHandler() { 56 | c := make(chan os.Signal, 1) 57 | signal.Notify(c, os.Interrupt, syscall.SIGTERM) 58 | go func() { 59 | <-c 60 | logger.Error("Test execution was aborted by user") 61 | os.Exit(int(command.Aborted)) 62 | }() 63 | } 64 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | paths-ignore: 6 | - "**/*.md" 7 | 8 | jobs: 9 | CI: 10 | name: CI 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v6 14 | with: 15 | persist-credentials: false 16 | - uses: actions/setup-go@v6 17 | with: 18 | go-version-file: go.mod 19 | 20 | - name: Setup GO environment 21 | run: | 22 | go mod download 23 | go get -u golang.org/x/lint/golint 24 | go get -t . 25 | 26 | - name: Vet 27 | run: | 28 | go vet ./... 29 | 30 | - name: Unit tests 31 | run: | 32 | make test 33 | make test-cov 34 | 35 | - name: Quality Gate - Test coverage shall be above threshold 36 | env: 37 | TESTCOVERAGE_THRESHOLD: 4 38 | run: | 39 | echo "Quality Gate: checking test coverage is above threshold ..." 40 | echo "Threshold : $TESTCOVERAGE_THRESHOLD %" 41 | totalCoverage=`go tool cover -func=coverage.out | grep total | grep -Eo '[0-9]+\.[0-9]+'` 42 | echo "Current test coverage : $totalCoverage %" 43 | if (( $(echo "$totalCoverage $TESTCOVERAGE_THRESHOLD" | awk '{print ($1 > $2)}') )); then 44 | echo "OK" 45 | else 46 | echo "Current test coverage is below threshold. Please add more unit tests or adjust threshold to a lower value." 47 | echo "Failed" 48 | exit 1 49 | fi 50 | acceptance: 51 | name: Acceptance Tests 52 | runs-on: ubuntu-latest 53 | steps: 54 | - uses: actions/checkout@v6 55 | with: 56 | persist-credentials: false 57 | - uses: actions/setup-go@v6 58 | with: 59 | go-version-file: go.mod 60 | - name: Build 61 | run: make -B build 62 | 63 | - name: Acceptance tests 64 | run: ./build/github/acceptance_test.sh 65 | -------------------------------------------------------------------------------- /cmd/generate-plugin.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | "github.com/spf13/viper" 6 | 7 | "github.com/privateerproj/privateer-sdk/command" 8 | ) 9 | 10 | var ( 11 | // genPluginCmd represents the generate-plugin command. 12 | // It generates a new Privateer plugin from a source file using templates. 13 | genPluginCmd = &cobra.Command{ 14 | Use: "generate-plugin", 15 | Short: "Generate a new plugin", 16 | Run: func(cmd *cobra.Command, args []string) { 17 | generatePlugin() 18 | }, 19 | } 20 | ) 21 | 22 | func init() { 23 | genPluginCmd.PersistentFlags().StringP("source-path", "p", "", "The source file to generate the plugin from") 24 | genPluginCmd.PersistentFlags().StringP("local-templates", "", "", "Path to a directory to use instead of downloading the latest templates") 25 | genPluginCmd.PersistentFlags().StringP("service-name", "n", "", "The name of the service (e.g. 'ECS, AKS, GCS')") 26 | genPluginCmd.PersistentFlags().StringP("output-dir", "o", "generated-plugin/", "Pathname for the generated plugin") 27 | 28 | _ = viper.BindPFlag("source-path", genPluginCmd.PersistentFlags().Lookup("source-path")) 29 | _ = viper.BindPFlag("local-templates", genPluginCmd.PersistentFlags().Lookup("local-templates")) 30 | _ = viper.BindPFlag("service-name", genPluginCmd.PersistentFlags().Lookup("service-name")) 31 | _ = viper.BindPFlag("output-dir", genPluginCmd.PersistentFlags().Lookup("output-dir")) 32 | 33 | rootCmd.AddCommand(genPluginCmd) 34 | } 35 | 36 | // generatePlugin sets up the templating environment and generates a new plugin 37 | // based on the provided source file, service name, and output directory. 38 | // It handles errors by logging them and returning early. 39 | func generatePlugin() { 40 | templatesDir, sourcePath, outputDir, serviceName, err := command.SetupTemplatingEnvironment(logger) 41 | if err != nil { 42 | logger.Error(err.Error()) 43 | return 44 | } 45 | 46 | err = command.GeneratePlugin(logger, templatesDir, sourcePath, outputDir, serviceName) 47 | if err != nil { 48 | logger.Error(err.Error()) 49 | return 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Ref: https://www.digitalocean.com/community/tutorials/using-ldflags-to-set-version-information-for-go-applications 2 | 3 | BUILD_FLAGS=-X 'main.GitCommitHash=`git rev-parse --short HEAD`' -X 'main.BuiltAt=`date +%FT%T%z`' -X 'main.Version=`git describe --tags`' 4 | BUILD_WIN=@env GOOS=windows GOARCH=amd64 go build -o privateer-windows.exe 5 | BUILD_LINUX=@env GOOS=linux GOARCH=amd64 go build -o privateer-linux 6 | BUILD_MAC=@env GOOS=darwin GOARCH=amd64 go build -o privateer-darwin 7 | 8 | build: tidy test binary 9 | testcov: test test-cov 10 | release: tidy test release-nix release-win release-mac 11 | 12 | binary: 13 | @echo " > Building binary ..." 14 | go build -o privateer -ldflags="$(BUILD_FLAGS)" 15 | 16 | test: 17 | @echo " > Validating code ..." 18 | @go vet ./... 19 | @go test ./... 20 | 21 | tidy: 22 | @echo " > Tidying go.mod ..." 23 | @go mod tidy 24 | 25 | test-cov: 26 | @echo "Running tests and generating coverage output ..." 27 | @go test ./... -coverprofile coverage.out -covermode count 28 | @sleep 2 # Sleeping to allow for coverage.out file to get generated 29 | @echo "Current test coverage : $(shell go tool cover -func=coverage.out | grep total | grep -Eo '[0-9]+\.[0-9]+') %" 30 | 31 | release-candidate: tidy test 32 | @echo " > Building release candidate for Linux..." 33 | $(BUILD_LINUX) -ldflags="$(BUILD_FLAGS) -X 'main.VersionPostfix=nix-rc'" 34 | @echo " > Building release candidate for Windows..." 35 | $(BUILD_WIN) -ldflags="$(BUILD_FLAGS) -X 'main.VersionPostfix=win-rc'" 36 | @echo " > Building release for Darwin..." 37 | $(BUILD_MAC) -ldflags="$(BUILD_FLAGS) -X 'main.VersionPostfix=darwin'" 38 | 39 | release-nix: 40 | @echo " > Building release for Linux..." 41 | $(BUILD_LINUX) -ldflags="$(BUILD_FLAGS) -X 'main.VersionPostfix=linux'" 42 | 43 | release-win: 44 | @echo " > Building release for Windows..." 45 | $(BUILD_WIN) -ldflags="$(BUILD_FLAGS) -X 'main.VersionPostfix=windows'" 46 | 47 | release-mac: 48 | @echo " > Building release for Darwin..." 49 | $(BUILD_MAC) -ldflags="$(BUILD_FLAGS) -X 'main.VersionPostfix=darwin'" 50 | 51 | todo: 52 | @read -p "Write your todo here: " TODO; \ 53 | echo "- [ ] $$TODO" >> TODO.md 54 | -------------------------------------------------------------------------------- /.github/security-insights.yml: -------------------------------------------------------------------------------- 1 | header: 2 | schema-version: 2.0.0 3 | last-updated: '2021-09-01' 4 | last-reviewed: '2022-09-01' 5 | url: https://github.com/privateerproj/privateer/blob/main/.github/security-insights.yml 6 | project-si-source: https://raw.githubusercontent.com/privateerproj/.github/refs/heads/main/.github/security-insights.yml 7 | comment: | 8 | This file contains only the repository information for the core Privateer CLI. 9 | 10 | repository: 11 | url: https://github.com/privateerproj/privateer 12 | status: active 13 | bug-fixes-only: false 14 | accepts-change-request: true 15 | accepts-automated-change-request: true 16 | no-third-party-packages: false 17 | core-team: 18 | - name: Eddie Knight 19 | affiliation: Sonatype 20 | social: https://bsky.app/profile/eddieknight.dev 21 | primary: true 22 | - name: Jason Meridth 23 | affiliation: GitHub 24 | primary: false 25 | - name: Rudra Gupta 26 | affiliation: Krumware 27 | primary: false 28 | documentation: 29 | contributing-guide: https://github.com/privateerproj/.github/blob/main/.github/CONTRIBUTING.md 30 | security-policy: https://github.com/privateerproj/.github/blob/main/.github/SECURITY.md 31 | license: 32 | url: https://github.com/privateerproj/privateer?tab=Apache-2.0-1-ov-file#readme 33 | expression: Apache-2.0 34 | release: 35 | changelog: https://github.com/privateerproj/privateer/releases 36 | automated-pipeline: true 37 | distribution-points: 38 | - uri: https://github.com/privateerproj/privateer/releases 39 | comment: GitHub Release Page 40 | license: 41 | url: https://foo.bar/release/{version}#license 42 | expression: MIT AND Apache-2.0 43 | security: 44 | assessments: 45 | self: 46 | comment: | 47 | A self assessment has not been published for this repo. 48 | champions: 49 | - name: Jason Meridth 50 | primary: true 51 | tools: 52 | - name: Dependabot 53 | type: SCA 54 | version: "2" 55 | rulesets: 56 | - built-in 57 | results: 58 | adhoc: 59 | name: Scheduled SCA Scan Results 60 | predicate-uri: https://docs.github.com/en/graphql/reference/objects#repositoryvulnerabilityalert 61 | location: https://github.com/privateerproj/privateer/security/dependabot 62 | comment: | 63 | The results of the scheduled SCA scan are available in the Dependabot tab of the Security Insights page. 64 | integration: 65 | adhoc: true 66 | ci: false 67 | release: false 68 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/privateerproj/privateer 2 | 3 | go 1.25.1 4 | 5 | require ( 6 | github.com/hashicorp/go-hclog v1.6.3 7 | github.com/privateerproj/privateer-sdk v1.15.3 8 | github.com/spf13/cobra v1.10.2 9 | github.com/spf13/viper v1.21.0 10 | ) 11 | 12 | require ( 13 | dario.cat/mergo v1.0.1 // indirect 14 | github.com/Microsoft/go-winio v0.6.2 // indirect 15 | github.com/ProtonMail/go-crypto v1.1.6 // indirect 16 | github.com/cloudflare/circl v1.6.1 // indirect 17 | github.com/cyphar/filepath-securejoin v0.4.1 // indirect 18 | github.com/defenseunicorns/go-oscal v0.7.0 // indirect 19 | github.com/emirpasic/gods v1.18.1 // indirect 20 | github.com/fatih/color v1.18.0 // indirect 21 | github.com/fsnotify/fsnotify v1.9.0 // indirect 22 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect 23 | github.com/go-git/go-billy/v5 v5.6.2 // indirect 24 | github.com/go-git/go-git/v5 v5.16.4 // indirect 25 | github.com/go-viper/mapstructure/v2 v2.4.0 // indirect 26 | github.com/goccy/go-yaml v1.18.0 // indirect 27 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect 28 | github.com/golang/protobuf v1.5.4 // indirect 29 | github.com/google/uuid v1.6.0 // indirect 30 | github.com/hashicorp/go-plugin v1.7.0 // indirect 31 | github.com/hashicorp/yamux v0.1.2 // indirect 32 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 33 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect 34 | github.com/kevinburke/ssh_config v1.2.0 // indirect 35 | github.com/mattn/go-colorable v0.1.14 // indirect 36 | github.com/mattn/go-isatty v0.0.20 // indirect 37 | github.com/oklog/run v1.1.0 // indirect 38 | github.com/ossf/gemara v0.17.0 // indirect 39 | github.com/pelletier/go-toml/v2 v2.2.4 // indirect 40 | github.com/pjbgf/sha1cd v0.3.2 // indirect 41 | github.com/sagikazarmark/locafero v0.11.0 // indirect 42 | github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect 43 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect 44 | github.com/skeema/knownhosts v1.3.1 // indirect 45 | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect 46 | github.com/spf13/afero v1.15.0 // indirect 47 | github.com/spf13/cast v1.10.0 // indirect 48 | github.com/spf13/pflag v1.0.10 // indirect 49 | github.com/subosito/gotenv v1.6.0 // indirect 50 | github.com/xanzy/ssh-agent v0.3.3 // indirect 51 | go.yaml.in/yaml/v3 v3.0.4 // indirect 52 | golang.org/x/crypto v0.45.0 // indirect 53 | golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 // indirect 54 | golang.org/x/net v0.47.0 // indirect 55 | golang.org/x/sys v0.38.0 // indirect 56 | golang.org/x/text v0.31.0 // indirect 57 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect 58 | google.golang.org/grpc v1.71.0 // indirect 59 | google.golang.org/protobuf v1.36.6 // indirect 60 | gopkg.in/warnings.v0 v0.1.2 // indirect 61 | gopkg.in/yaml.v3 v3.0.1 // indirect 62 | ) 63 | 64 | // For SDK Development Only 65 | // replace github.com/privateerproj/privateer-sdk => ../privateer-sdk 66 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | // Package cmd provides the command-line interface for Privateer. 2 | // It defines the root command and all subcommands, handles configuration, 3 | // and manages the execution flow of the application. 4 | package cmd 5 | 6 | import ( 7 | "os" 8 | "path" 9 | "text/tabwriter" 10 | 11 | hclog "github.com/hashicorp/go-hclog" 12 | "github.com/spf13/cobra" 13 | "github.com/spf13/viper" 14 | 15 | "github.com/privateerproj/privateer-sdk/command" 16 | "github.com/privateerproj/privateer-sdk/config" 17 | ) 18 | 19 | var ( 20 | // buildVersion holds the version string set at build time. 21 | buildVersion string 22 | // buildGitCommitHash holds the git commit hash set at build time. 23 | buildGitCommitHash string 24 | // buildTime holds the build timestamp set at build time. 25 | buildTime string 26 | 27 | // logger enables formatted logging with methods like logger.Trace, logger.Info, etc. 28 | logger hclog.Logger 29 | // writer enables formatted tabular output for use in list and version commands. 30 | writer *tabwriter.Writer 31 | 32 | // rootCmd represents the base command when called without any subcommands. 33 | // It is the entry point for all Privateer commands and handles global configuration. 34 | rootCmd = &cobra.Command{ 35 | Use: "privateer", 36 | Short: "privateer root command", 37 | PersistentPreRun: persistentPreRun, 38 | } 39 | ) 40 | 41 | // Execute adds all child commands to the root command and sets flags appropriately. 42 | // This is called by main.main(). It only needs to happen once to the rootCmd. 43 | // 44 | // Parameters: 45 | // - version: The version string to display in version command 46 | // - commitHash: The git commit hash to display in version command 47 | // - builtAt: The build timestamp to display in version command 48 | func Execute(version, commitHash, builtAt string) { 49 | buildVersion = version 50 | buildGitCommitHash = commitHash 51 | buildTime = builtAt 52 | 53 | err := rootCmd.Execute() 54 | if err != nil { 55 | os.Exit(1) 56 | } 57 | } 58 | 59 | func init() { 60 | command.SetBase(rootCmd) 61 | rootCmd.PersistentFlags().StringP("binaries-path", "b", defaultBinariesPath(), "Path to the directory where plugins are installed") 62 | _ = viper.BindPFlag("binaries-path", rootCmd.PersistentFlags().Lookup("binaries-path")) 63 | } 64 | 65 | // persistentPreRun initializes the logger and writer for use by all commands. 66 | // It is called before every command execution and sets up the configuration 67 | // and output formatting utilities. 68 | func persistentPreRun(cmd *cobra.Command, args []string) { 69 | cfg := config.NewConfig(nil) 70 | logger = cfg.Logger 71 | 72 | // writer is used for output in the list & version commands 73 | writer = tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) 74 | command.ReadConfig() 75 | } 76 | 77 | // defaultBinariesPath returns the default path where plugins are installed. 78 | // It constructs a path in the user's home directory under .privateer/bin. 79 | func defaultBinariesPath() string { 80 | home, _ := os.UserHomeDir() 81 | return path.Join(home, ".privateer", "bin") 82 | } 83 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # Constants 6 | DEFAULT_INSTALL_DIR="$HOME/.privateer/bin" 7 | PRIVATEER_REPO="privateerproj/privateer" 8 | LATEST_RELEASE_URL="https://api.github.com/repos/${PRIVATEER_REPO}/releases/latest" 9 | 10 | # Detect OS (darwin = macOS, linux = Linux, msys or cygwin = Windows) 11 | OS="" 12 | case "$(uname -s)" in 13 | Darwin) 14 | OS="darwin" 15 | ;; 16 | Linux) 17 | OS="linux" 18 | ;; 19 | CYGWIN*|MSYS*|MINGW*) 20 | OS="windows" 21 | ;; 22 | *) 23 | echo "Unsupported Environment: $(uname -s)" 24 | exit 1 25 | ;; 26 | esac 27 | 28 | # Detect Architecture (x86_64 = amd64, arm64 = arm64, i386/i686 = 386) 29 | ARCH="" 30 | case "$(uname -m)" in 31 | x86_64) 32 | ARCH="x86_64" 33 | ;; 34 | i386) 35 | ARCH="i386" 36 | ;; 37 | arm64) 38 | ARCH="arm64" 39 | ;; 40 | *) 41 | echo "Unsupported Architecture: $(uname -m)" 42 | exit 1 43 | ;; 44 | esac 45 | 46 | download_latest_release() { 47 | local install_dir="$1" 48 | local install_file="$install_dir/privateer" 49 | 50 | # Ensure the directory exists 51 | mkdir -p "$install_dir" 52 | 53 | # Build the grep pattern based on OS 54 | local pattern 55 | if [[ "$OS" == "darwin" ]]; then 56 | pattern="browser_download_url.*${OS}.*" 57 | else 58 | pattern="browser_download_url.*${OS}.*${ARCH}.*" 59 | fi 60 | 61 | # Fetch the download URL for the latest release 62 | local url 63 | url=$(curl -s ${LATEST_RELEASE_URL} | grep -i "$pattern" | cut -d '"' -f 4) 64 | 65 | if [[ -z "$url" ]]; then 66 | echo "Failed to fetch the download URL for the latest release." 67 | exit 1 68 | fi 69 | 70 | echo "Downloading from: $url" 71 | 72 | # Download the binary to the specified install directory 73 | curl -L -0 "$url" | tar xvf - -C "$install_dir" 74 | 75 | if [[ $? -ne 0 ]]; then 76 | echo "Failed to download the binary." 77 | exit 1 78 | fi 79 | 80 | # Ensure the binary is executable 81 | chmod +x "$install_file" 82 | 83 | echo "Downloaded binary to $install_file" 84 | } 85 | 86 | update_path() { 87 | local install_dir="$1" 88 | 89 | # Check if the install directory is already in PATH 90 | if [[ ":$PATH:" != *":$install_dir:"* ]]; then 91 | echo "$install_dir is not in the PATH." 92 | 93 | # Detect current shell 94 | current_shell=$(basename "$SHELL") 95 | 96 | case "$current_shell" in 97 | bash) 98 | config_file="$HOME/.bash_profile" 99 | ;; 100 | zsh) 101 | config_file="$HOME/.zshrc" 102 | ;; 103 | fish) 104 | config_file="$HOME/.config/fish/config.fish" 105 | ;; 106 | *) 107 | echo "Unsupported shell: $current_shell. You may need to manually add $install_dir to your PATH." 108 | return 109 | ;; 110 | esac 111 | 112 | # Check if the path is already added to the config file 113 | if ! grep -q "$install_dir" "$config_file"; then 114 | echo "export PATH=\"$install_dir:\$PATH\"" >> "$config_file" 115 | echo "$install_dir added to $config_file" 116 | source $config_file 117 | else 118 | echo "$install_dir is already in $config_file." 119 | fi 120 | else 121 | echo "$install_dir is already in the PATH." 122 | fi 123 | } 124 | 125 | # Main logic 126 | main() { 127 | local install_dir="$DEFAULT_INSTALL_DIR" 128 | 129 | # Handle CLI arguments for installation path override 130 | while getopts "p:" opt; do 131 | case $opt in 132 | p) 133 | install_dir="$OPTARG" 134 | ;; 135 | *) 136 | echo "Usage: $0 [-p install_path]" 137 | exit 1 138 | ;; 139 | esac 140 | done 141 | 142 | mkdir -p "$install_dir" 143 | 144 | # Download the latest release 145 | download_latest_release "$install_dir" 146 | 147 | # Ensure the binary is accessible via PATH 148 | update_path "$install_dir" 149 | 150 | echo "Privateer installation complete!" 151 | } 152 | 153 | main "$@" 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Privateer 2 | 3 | **Privateer** is a validation framework that simplifies infrastructure testing and compliance validation. Built with infrastructure engineers in mind, Privateer helps accelerate security and compliance validation of any software asset. 4 | 5 | ## Key Features 6 | 7 | - **Community-Driven Plugins**: Plugins are crafted and maintained collaboratively by the community or privately within your organization 8 | - **Comprehensive Resource Validation**: Validate diverse resources in a single execution, regardless of how many resources or validations you need to queue 9 | - **Consistent Machine-Readable Output**: Standardized output simplifies automation and integration 10 | - **Plugin Generation**: Generate plugin scaffolding from [Gemara](https://gemara.openssf.org) Layer 2 schema catalogs with the push of a button 11 | 12 | ## Quick Start 13 | 14 | **For detailed ecosystem documentation, visit [privateerproj.com](https://privateerproj.com)** 15 | 16 | ### Step 1: Star this Repo 17 | 18 | Click the star at the top right of this page so that you can find it easily the next time you sign in to GitHub. 19 | 20 | ### Step 2: Choose Your Installation Method 21 | 22 | **Option 1: Install via Script** 23 | 24 | ```bash 25 | /bin/bash -c "$(curl -sSL https://raw.githubusercontent.com/privateerproj/privateer/main/install.sh)" 26 | ``` 27 | 28 | **Option 2: Download from Releases** 29 | Download the latest release from [GitHub Releases](https://github.com/privateerproj/privateer/releases). 30 | 31 | **Option 3: Build from Source** 32 | ```bash 33 | git clone https://github.com/privateerproj/privateer.git 34 | cd privateer 35 | go mod tidy 36 | make build 37 | ``` 38 | 39 | ### Step 3: Choose Your Plugins 40 | 41 | We do not currently maintain an authoritative list of community plugins, but a good place to start would be the OpenSSF's [plugin](https://github.com/revanite-io/pvtr-github-repo) for scanning GitHub repos against the _Open Source Project Security Baseline_. 42 | 43 | ### Step 4: Install & Verify Your Plugins 44 | 45 | Plugin installation is currently left to the user. The default location for plugin binaries is `$HOME/.privateer/bin`. You may specify a different location at runtime via `--binaries-path` if you install your plugins elsewhere. 46 | 47 | To review the plugins you have installed, run `privateer list -a`. 48 | 49 | ## Contributing 50 | 51 | We welcome contributions! See our [Contributing Guidelines](https://github.com/privateerproj/privateer?tab=contributing-ov-file) for details. 52 | 53 | All contributions are covered by the [Apache 2 License](https://github.com/privateerproj/privateer?tab=Apache-2.0-1-ov-file) at the time the pull request is opened, and all community interactions are governed by our [Code of Conduct](https://github.com/privateerproj/privateer?tab=coc-ov-file). 54 | 55 | ### Local Development Prerequisites 56 | 57 | - **Go 1.25.1 or later** - Required for building Privateer and running tests 58 | - **Make** - For using the Makefile build targets 59 | 60 | ### Testing 61 | 62 | Run all tests: 63 | ```bash 64 | make test 65 | ``` 66 | 67 | Run tests with coverage: 68 | ```bash 69 | make testcov 70 | ``` 71 | 72 | ### Available Make Targets 73 | 74 | - `make binary` - Build the binary 75 | - `make test` - Run tests and vet checks 76 | - `make testcov` - Run tests with coverage report 77 | - `make tidy` - Clean up go.mod dependencies 78 | - `make release` - Build release binaries for all platforms 79 | - `make build` - Alias for `tidy test binary` 80 | 81 | ### Project Structure 82 | 83 | ``` 84 | privateer/ 85 | ├── cmd/ # CLI commands (run, list, generate-plugin, etc.) 86 | ├── test/ # Test data and fixtures 87 | ├── build/ # Build scripts and CI configurations 88 | ├── main.go # Application entry point 89 | └── go.mod # Go module dependencies 90 | ``` 91 | 92 | ## Security 93 | 94 | For vulnerability reporting, please reference our [Security Policy](https://github.com/privateerproj/privateer?tab=security-ov-file). For security questions, please search our closed issues and open a new issue if your question has not yet been answered. 95 | 96 | ## Helpful Links 97 | 98 | - **[Privateer SDK](https://github.com/privateerproj/privateer-sdk)** - SDK for developing Privateer plugins 99 | - **[Privateer Documentation](https://privateerproj.com)** - Complete documentation site 100 | - **[Example Plugin](https://github.com/privateerproj/raid-wireframe)** - Reference implementation 101 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2025 Revanite Incorporated 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= 2 | dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= 3 | github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 4 | github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= 5 | github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 6 | github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= 7 | github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= 8 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= 9 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= 10 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 11 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 12 | github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= 13 | github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= 14 | github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= 15 | github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= 16 | github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= 17 | github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= 18 | github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= 19 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 20 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 21 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 22 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 23 | github.com/defenseunicorns/go-oscal v0.7.0 h1:Ji9Yw3zEkbUfKZ8Gotoi9ExjUV/h3jmFLJBCYWkDN3E= 24 | github.com/defenseunicorns/go-oscal v0.7.0/go.mod h1:OPuLRz6v7qhSaKIUgr+bK6ykhYq7FpZozSn2cVZJhMs= 25 | github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= 26 | github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= 27 | github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= 28 | github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= 29 | github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= 30 | github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= 31 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 32 | github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= 33 | github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= 34 | github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= 35 | github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 36 | github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= 37 | github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= 38 | github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= 39 | github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= 40 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= 41 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= 42 | github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= 43 | github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= 44 | github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= 45 | github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= 46 | github.com/go-git/go-git/v5 v5.16.4 h1:7ajIEZHZJULcyJebDLo99bGgS0jRrOxzZG4uCk2Yb2Y= 47 | github.com/go-git/go-git/v5 v5.16.4/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= 48 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 49 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 50 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 51 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 52 | github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= 53 | github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= 54 | github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= 55 | github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= 56 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= 57 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= 58 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 59 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 60 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 61 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 62 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 63 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 64 | github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= 65 | github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= 66 | github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= 67 | github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= 68 | github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= 69 | github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= 70 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 71 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 72 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 73 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 74 | github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= 75 | github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= 76 | github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= 77 | github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 78 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 79 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 80 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 81 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 82 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 83 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 84 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 85 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 86 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 87 | github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= 88 | github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= 89 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 90 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 91 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 92 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 93 | github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= 94 | github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= 95 | github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= 96 | github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= 97 | github.com/ossf/gemara v0.17.0 h1:iycpGdJuqyZjUEpRjZzSPE21LAJPS94AnXXF+gMUEKk= 98 | github.com/ossf/gemara v0.17.0/go.mod h1:rY4YvaWvOSJthTE2jHudjwcCRIQ31Y7GpEc3pyJPIPM= 99 | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= 100 | github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 101 | github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= 102 | github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= 103 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 104 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 105 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 106 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 107 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 108 | github.com/privateerproj/privateer-sdk v1.15.3 h1:T9XzVjdqPYykPewF53BdqcXUB7Ootsr0qHFWMrmAZkI= 109 | github.com/privateerproj/privateer-sdk v1.15.3/go.mod h1:dgjEJVSEVJOXeyK2HUmkPBP149Pv5XvftPcmmCL1cO4= 110 | github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= 111 | github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 112 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 113 | github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= 114 | github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= 115 | github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ= 116 | github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= 117 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= 118 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= 119 | github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 120 | github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= 121 | github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= 122 | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= 123 | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= 124 | github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= 125 | github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= 126 | github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= 127 | github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= 128 | github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= 129 | github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= 130 | github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 131 | github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= 132 | github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 133 | github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= 134 | github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= 135 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 136 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 137 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 138 | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 139 | github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= 140 | github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 141 | github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= 142 | github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= 143 | github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= 144 | github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= 145 | go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= 146 | go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 147 | go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= 148 | go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= 149 | go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= 150 | go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= 151 | go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= 152 | go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= 153 | go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= 154 | go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= 155 | go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= 156 | go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= 157 | go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= 158 | go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= 159 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 160 | golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= 161 | golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= 162 | golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 h1:aWwlzYV971S4BXRS9AmqwDLAD85ouC6X+pocatKY58c= 163 | golang.org/x/exp v0.0.0-20250228200357-dead58393ab7/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= 164 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 165 | golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= 166 | golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= 167 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 168 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 169 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 170 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 171 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 172 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 173 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 174 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 175 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 176 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 177 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 178 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 179 | golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= 180 | golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 181 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 182 | golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= 183 | golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= 184 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 185 | golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= 186 | golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= 187 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 188 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= 189 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= 190 | google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= 191 | google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= 192 | google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= 193 | google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= 194 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 195 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 196 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 197 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 198 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 199 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 200 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 201 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 202 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 203 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 204 | -------------------------------------------------------------------------------- /test/data/OSPS_Baseline_AC_2025_02.yaml: -------------------------------------------------------------------------------- 1 | metadata: 2 | title: CCC Virtual Private Cloud 3 | id: CCC.VPC 4 | description: | 5 | This documents the minimal set of features that should be present 6 | for a virtual private cloud service to be considered for use in financial 7 | services ecosystems. 8 | release_details: 9 | - version: "2025.01" 10 | assurance_level: None 11 | threat_model_url: None 12 | threat_model_author: None 13 | red_team: None 14 | red_team_exercise_url: None 15 | release_manager: 16 | name: Damien Burks 17 | github_id: damienjburks 18 | company: Citi 19 | summary: | 20 | This initial release is part of the first batch of control catalogs 21 | produced by the CCC. It is the result of thousands of hours dedicated to 22 | exploring different ways of working and collaborating, on top of time 23 | spent researching, writing, and reviewing the content. This marks a huge 24 | milestone for the CCC and the broader community as further releases will 25 | continue to build on this foundation. A huge thanks to everyone who has 26 | brought us to this point! 27 | change_log: 28 | - | 29 | This initial release contains a variety of commits designed to capture 30 | all of the features, threats, and controls for this service category. 31 | contributors: 32 | - name: Michael Lysaght 33 | github_id: mlysaght2017 34 | company: Citi 35 | - name: Sonali Mendis 36 | github_id: smendis-scottlogic 37 | company: Scott Logic 38 | - name: Eddie Knight 39 | github_id: eddie-knight 40 | company: Sonatype 41 | - name: Dave Ogle 42 | github_id: dogle-scottlogic 43 | company: Scott Logic 44 | - name: kazmik23 45 | github_id: kazmik23 46 | company: Google 47 | controls: 48 | - id: CCC.C01 49 | title: Prevent Unencrypted Requests 50 | objective: | 51 | Ensure that all communications are encrypted in transit to protect data 52 | integrity and confidentiality. 53 | control_family: Data 54 | threats: 55 | - CCC.TH02 56 | nist_csf: PR.DS-02 57 | control_mappings: 58 | CCM: 59 | - IVS-03 60 | - IVS-07 61 | ISO_27001: 62 | - 2013 A.13.1.1 63 | NIST_800_53: 64 | - SC-8 65 | - SC-13 66 | test_requirements: 67 | - id: CCC.C01.TR01 68 | text: | 69 | When a port is exposed for non-SSH network traffic, all traffic MUST 70 | include a TLS handshake AND be encrypted using TLS 1.2 or higher. 71 | tlp_levels: 72 | - tlp_clear 73 | - tlp_green 74 | - tlp_amber 75 | - tlp_red 76 | - id: CCC.C01.TR02 77 | text: | 78 | When a port is exposed for SSH network traffic, all traffic MUST 79 | include a SSH handshake AND be encrypted using SSHv2 or higher. 80 | tlp_levels: 81 | - tlp_clear 82 | - tlp_green 83 | - tlp_amber 84 | - tlp_red 85 | link: cccc01---prevent-unencrypted-requests 86 | - id: CCC.C02 87 | title: Ensure Data Encryption at Rest for All Stored Data 88 | objective: | 89 | Ensure that all data stored is encrypted at rest to maintain 90 | confidentiality and integrity. 91 | control_family: Encryption 92 | threats: 93 | - CCC.TH01 94 | nist_csf: PR.DS-1 95 | control_mappings: 96 | CCM: [] 97 | ISO_27001: [] 98 | NIST_800_53: 99 | - SC-13 100 | - SC-28 101 | test_requirements: 102 | - id: CCC.C02.TR01 103 | text: | 104 | When data is stored at rest, the service MUST be configured to 105 | encrypt data at rest using the latest industry-standard encryption 106 | methods. 107 | tlp_levels: 108 | - tlp_clear 109 | - tlp_green 110 | - tlp_amber 111 | - tlp_red 112 | link: cccc02---ensure-data-encryption-at-rest-for-all-stored-data 113 | - id: CCC.C03 114 | title: Implement Multi-factor Authentication (MFA) for Access 115 | objective: | 116 | Ensure that all sensitive activities require two or more identity factors 117 | during authentication to prevent unauthorized access. This may include 118 | something you know, something you have, or something you are. In the 119 | case of programattically accessible services, such as API endpoints, this 120 | includes a combination of API keys or tokens and network restrictions. 121 | control_family: Identity and Access Management 122 | threats: 123 | - CCC.TH01 124 | nist_csf: PR.AC-7 125 | control_mappings: 126 | CCM: 127 | - IAM-03 128 | - IAM-08 129 | ISO_27001: 130 | - 2013 A.9.4.2 131 | NIST_800_53: 132 | - IA-2 133 | test_requirements: 134 | - id: CCC.C03.TR01 135 | text: | 136 | When an entity attempts to modify the service, the service MUST 137 | attempt to verify the client's identity through an authentication 138 | process. 139 | tlp_levels: 140 | - tlp_clear 141 | - tlp_green 142 | - tlp_amber 143 | - tlp_red 144 | - id: CCC.C03.TR02 145 | text: | 146 | When an entity attempts to view information presented by the service, 147 | service, the service MUST attempt to verify the client's identity 148 | through an authentication process. 149 | tlp_levels: 150 | - tlp_amber 151 | - tlp_red 152 | - id: CCC.C03.TR03 153 | text: | 154 | When an entity attempts to view information on the service through 155 | a user interface, the authentication process MUST require multiple 156 | identifying factors from the user. 157 | tlp_levels: 158 | - tlp_amber 159 | - tlp_red 160 | - id: CCC.C03.TR04 161 | text: | 162 | When an entity attempts to modify the service through an API 163 | endpoint, the authentication process MUST be limited to a 164 | specific allowed network. 165 | tlp_levels: 166 | - tlp_clear 167 | - tlp_green 168 | - tlp_amber 169 | - tlp_red 170 | - id: CCC.C03.TR05 171 | text: | 172 | When an entity attempts to view information on the service through 173 | an API endpoint, the authentication process MUST be limited to a 174 | specific allowed network. 175 | tlp_levels: 176 | - tlp_amber 177 | - tlp_red 178 | - id: CCC.C03.TR06 179 | text: | 180 | When an entity attempts to modify the service through a user 181 | interface, the authentication process MUST require multiple 182 | identifying factors from the user. 183 | tlp_levels: 184 | - tlp_clear 185 | - tlp_green 186 | - tlp_amber 187 | - tlp_red 188 | link: cccc03---implement-multi-factor-authentication-(mfa)-for-access 189 | - id: CCC.C04 190 | title: Log All Access and Changes 191 | objective: | 192 | Ensure that all access and changes are logged to maintain a 193 | detailed audit trail for security and compliance purposes. 194 | control_family: Logging & Monitoring 195 | threats: 196 | - CCC.TH01 197 | nist_csf: DE.AE-3 198 | control_mappings: 199 | CCM: [] 200 | ISO_27001: [] 201 | NIST_800_53: 202 | - AU-2 203 | - AU-3 204 | - AU-12 205 | test_requirements: 206 | - id: CCC.C04.TR01 207 | text: | 208 | When any access attempt is made to the service, the service MUST log 209 | the client identity, time, and result of the attempt. 210 | tlp_levels: 211 | - tlp_amber 212 | - tlp_red 213 | - id: CCC.C04.TR02 214 | text: | 215 | When any access attempt is made to the view sensitive information, 216 | the service MUST log the client identity, time, and result of the 217 | attempt. 218 | tlp_levels: 219 | - tlp_amber 220 | - tlp_red 221 | - id: CCC.C04.TR03 222 | text: | 223 | When any change is made to the service configuration, the service MUST 224 | log the change, including the client, time, previous state, and the 225 | new state following the change. 226 | tlp_levels: 227 | - tlp_clear 228 | - tlp_green 229 | - tlp_amber 230 | - tlp_red 231 | link: cccc04---log-all-access-and-changes 232 | - id: CCC.C05 233 | title: Prevent Access from Untrusted Entities 234 | objective: | 235 | Ensure that secure access controls prevent unauthorized access, 236 | mitigate risks of data exfiltration, and block misuse of services 237 | by adversaries. This includes restricting access based on trust 238 | criteria such as IP allowlists, domain restrictions, and tenant 239 | isolation. 240 | control_family: Identity and Access Management 241 | threats: 242 | - CCC.TH01 243 | nist_csf: PR.AC-3 244 | control_mappings: 245 | CCM: 246 | - DS-5 247 | ISO_27001: 248 | - 2013 A.13.1.3 249 | NIST_800_53: 250 | - AC-3 251 | test_requirements: 252 | - id: CCC.C05.TR01 253 | text: | 254 | When access to sensitive resources is attempted, the service MUST 255 | block requests from untrusted sources, including IP addresses, 256 | domains, or networks that are not explicitly included in a 257 | pre-approved allowlist. 258 | tlp_levels: 259 | - tlp_amber 260 | - tlp_red 261 | - id: CCC.C05.TR02 262 | text: | 263 | When administrative access is attempted, the service MUST validate 264 | that the request originates from an explicitly allowed source as 265 | defined in the allowlist. 266 | tlp_levels: 267 | - tlp_clear 268 | - tlp_green 269 | - tlp_amber 270 | - tlp_red 271 | - id: CCC.C05.TR03 272 | text: | 273 | When resources are accessed in a multi-tenant environment, the 274 | service MUST enforce isolation by allowing access only to explicitly 275 | allowlisted tenants. 276 | tlp_levels: 277 | - tlp_amber 278 | - tlp_red 279 | - id: CCC.C05.TR04 280 | text: | 281 | When an access attempt from an untrusted source is blocked, the 282 | service MUST log the event, including the source details, time, 283 | and reason for denial. 284 | tlp_levels: 285 | - tlp_clear 286 | - tlp_green 287 | - tlp_amber 288 | - tlp_red 289 | link: cccc05---prevent-access-from-untrusted-entities 290 | - id: CCC.C06 291 | title: Prevent Deployment in Restricted Regions 292 | objective: | 293 | Ensure that resources are not provisioned or deployed in 294 | geographic regions or cloud availability zones that have been 295 | designated as restricted or prohibited, to comply with 296 | regulatory requirements and reduce exposure to geopolitical 297 | risks. 298 | control_family: Data 299 | threats: 300 | - CCC.TH03 301 | nist_csf: PR.DS-1 302 | control_mappings: 303 | CCM: 304 | - DSI-06 305 | - DSI-08 306 | ISO_27001: 307 | - 2013 A.11.1.1 308 | NIST_800_53: 309 | - AC-6 310 | test_requirements: 311 | - id: CCC.C06.TR01 312 | text: | 313 | When a deployment request is made, the service MUST validate 314 | that the deployment region is not to a restricted or regions 315 | or availability zones. 316 | tlp_levels: 317 | - tlp_clear 318 | - tlp_green 319 | - tlp_amber 320 | - tlp_red 321 | - id: CCC.C06.TR02 322 | text: | 323 | When a deployment request is made, the service MUST validate that 324 | replication of data, backups, and disaster recovery operations 325 | will not occur in restricted regions or availability zones. 326 | tlp_levels: 327 | - tlp_clear 328 | - tlp_green 329 | - tlp_amber 330 | - tlp_red 331 | link: cccc06---prevent-deployment-in-restricted-regions 332 | - id: CCC.C07 333 | title: Alert on Unusual Enumeration Activity 334 | objective: | 335 | Ensure that logs and associated alerts are generated when 336 | unusual enumeration activity is detected that may indicate 337 | reconnaissance activities. 338 | control_family: Logging & Monitoring 339 | threats: 340 | - CCC.TH15 341 | nist_csf: DE.AE-1 342 | control_mappings: 343 | CCM: [] 344 | ISO_27001: [] 345 | NIST_800_53: 346 | - AU-6 347 | test_requirements: 348 | - id: CCC.C07.TR01 349 | text: | 350 | When suspicious enumeration activities are detected, the 351 | service MUST generate real-time alerts to notify security 352 | personnel. 353 | tlp_levels: 354 | - tlp_red 355 | - id: CCC.C07.TR02 356 | text: | 357 | When suspicious enumeration activities are detected, the 358 | service MUST log the event, including the source details, 359 | time, and nature of the activity. 360 | tlp_levels: 361 | - tlp_clear 362 | - tlp_green 363 | - tlp_amber 364 | - tlp_red 365 | link: cccc07---alert-on-unusual-enumeration-activity 366 | - id: CCC.C08 367 | title: Enable Multi-zone or Multi-region Data Replication 368 | objective: | 369 | Ensure that data is replicated across multiple 370 | zones or regions to protect against data loss due to hardware 371 | failures, natural disasters, or other catastrophic events. 372 | control_family: Data 373 | threats: 374 | - CCC.TH06 375 | nist_csf: PR.PT-5 376 | control_mappings: 377 | CCM: [] 378 | ISO_27001: [] 379 | NIST_800_53: 380 | - CP-2 381 | - CP-10 382 | test_requirements: 383 | - id: CCC.C08.TR01 384 | text: | 385 | When data is stored, the service MUST ensure that data is 386 | replicated across multiple availability zones or regions. 387 | tlp_levels: 388 | - tlp_green 389 | - tlp_amber 390 | - tlp_red 391 | - id: CCC.C08.TR02 392 | text: | 393 | When data is replicated across multiple zones or regions, 394 | the service MUST be able to verify the replication state, 395 | including the replication locations and data synchronization 396 | status. 397 | tlp_levels: 398 | - tlp_green 399 | - tlp_amber 400 | - tlp_red 401 | link: cccc08---enable-multi-zone-or-multi-region-data-replication 402 | - id: CCC.C09 403 | title: Prevent Tampering, Deletion, or Unauthorized Access to Access Logs 404 | objective: | 405 | Access logs should always be considered sensitive. 406 | Ensure that access logs are protected against unauthorized 407 | access, tampering, or deletion. 408 | control_family: Data 409 | threats: 410 | - CCC.TH07 411 | - CCC.TH09 412 | - CCC.TH04 413 | nist_csf: PR.DS-6 414 | control_mappings: 415 | CCM: [] 416 | ISO_27001: [] 417 | NIST_800_53: 418 | - AU-9 419 | test_requirements: 420 | - id: CCC.C09.TR01 421 | text: | 422 | When access logs are stored, the service MUST ensure that 423 | access logs cannot be accessed without proper authorization. 424 | tlp_levels: 425 | - tlp_amber 426 | - tlp_red 427 | - tlp_green 428 | - tlp_clear 429 | - id: CCC.C09.TR02 430 | text: | 431 | When access logs are stored, the service MUST ensure that 432 | access logs cannot be modified without proper authorization. 433 | tlp_levels: 434 | - tlp_amber 435 | - tlp_red 436 | - tlp_green 437 | - tlp_clear 438 | - id: CCC.C09.TR03 439 | text: | 440 | When access logs are stored, the service MUST ensure that 441 | access logs cannot be deleted without proper authorization. 442 | tlp_levels: 443 | - tlp_amber 444 | - tlp_red 445 | - tlp_green 446 | - tlp_clear 447 | link: cccc09---prevent-tampering-deletion-or-unauthorized-access-to-access-logs 448 | - id: CCC.C10 449 | title: Prevent Data Replication to Destinations Outside of Defined Trust Perimeter 450 | objective: | 451 | Prevent replication of data to untrusted destinations outside 452 | of defined trust perimeter. An untrusted destination is defined 453 | as a resource that exists outside of a specified trusted 454 | identity or network or data perimeter. 455 | control_family: Data 456 | threats: 457 | - CCC.TH04 458 | nist_csf: PR.DS-5 459 | control_mappings: 460 | CCM: [] 461 | ISO_27001: [] 462 | NIST_800_53: 463 | - AC-4 464 | test_requirements: 465 | - id: CCC.C10.TR01 466 | text: | 467 | When data is replicated, the service MUST ensure that 468 | replication is restricted to explicitly trusted destinations. 469 | tlp_levels: 470 | - tlp_green 471 | - tlp_amber 472 | - tlp_red 473 | link: cccc10---prevent-data-replication-to-destinations-outside-of-defined-trust-perimeter 474 | - id: CCC.C11 475 | title: Enforce Key Management Policies 476 | objective: | 477 | Ensure that encryption keys are managed securely by enforcing 478 | the use of approved algorithms, regular key rotation, and 479 | customer-managed encryption keys (CMEKs). 480 | control_family: Encryption 481 | threats: 482 | - CCC.TH16 483 | nist_csf: PR.DS-1 484 | control_mappings: 485 | CCM: 486 | - EKM-02 487 | - EKM-03 488 | ISO_27001: 489 | - 2013 A.10.1.2 490 | NIST_800_53: 491 | - SC-12 492 | - SC-17 493 | test_requirements: 494 | - id: CCC.C11.TR01 495 | text: | 496 | When encryption keys are used, the service MUST verify that 497 | all encryption keys use approved cryptographic algorithms as 498 | per organizational standards. 499 | tlp_levels: 500 | - tlp_clear 501 | - tlp_green 502 | - tlp_amber 503 | - tlp_red 504 | - id: CCC.C11.TR02 505 | text: | 506 | When encryption keys are used, the service MUST verify that 507 | encryption keys are rotated at a frequency compliant with 508 | organizational policies. 509 | tlp_levels: 510 | - tlp_clear 511 | - tlp_green 512 | - tlp_amber 513 | - tlp_red 514 | - id: CCC.C11.TR03 515 | text: | 516 | When encrypting data, the service MUST verify that 517 | customer-managed encryption keys (CMEKs) are used. 518 | tlp_levels: 519 | - tlp_amber 520 | - tlp_red 521 | - id: CCC.C11.TR04 522 | text: | 523 | When encryption keys are accessed, the service MUST verify that 524 | access to encryption keys is restricted to authorized personnel 525 | and services, following the principle of least privilege. 526 | tlp_levels: 527 | - tlp_amber 528 | - tlp_red 529 | link: cccc11---enforce-key-management-policies 530 | - id: CCC.VPC.C01 531 | title: Restrict Default Network Creation 532 | objective: | 533 | Restrict the automatic creation of default virtual networks and related 534 | resources during subscription initialization to avoid insecure default 535 | configurations and enforce custom network policies. 536 | control_family: Network Security 537 | threats: 538 | - CCC.VPC.TH01 539 | nist_csf: PR.AC-5 540 | control_mappings: 541 | CCM: 542 | - TVM-02 543 | ISO_27001: 544 | - 2013 A.12.3.1 545 | NIST_800_53: 546 | - SC-7 547 | test_requirements: 548 | - id: CCC.VPC.C01.TR01 549 | text: | 550 | When a subscription is created, the subscription MUST NOT 551 | contain default network resources. 552 | tlp_levels: 553 | - tlp_amber 554 | - tlp_red 555 | link: cccvpcc01---restrict-default-network-creation 556 | - id: CCC.VPC.C02 557 | title: Limit Resource Creation in Public Subnet 558 | objective: | 559 | Restrict the creation of resources in the public subnet with 560 | direct access to the internet to minimize attack surfaces. 561 | control_family: Network Security 562 | threats: 563 | - CCC.VPC.TH02 564 | nist_csf: PR.AC-3 565 | control_mappings: 566 | CCM: 567 | - SEF-05 568 | ISO_27001: 569 | - 2013 A.13.1.1 570 | NIST_800_53: 571 | - AC-4 572 | test_requirements: 573 | - id: CCC.VPC.C02.TR01 574 | text: | 575 | When a resource is created in a public subnet, that resource 576 | MUST NOT be assigned an external IP address by default. 577 | tlp_levels: 578 | - tlp_red 579 | link: cccvpcc02---limit-resource-creation-in-public-subnet 580 | - id: CCC.VPC.C03 581 | title: Restrict VPC Peering to Authorized Accounts 582 | objective: | 583 | Ensure VPC peering connections are only established with explicitly 584 | authorized destinations to limit network exposure and enforce boundary 585 | controls. 586 | control_family: Network Security 587 | threats: 588 | - CCC.VPC.TH03 589 | nist_csf: PR.AC-3 590 | control_mappings: 591 | CCM: 592 | - IVS-01 593 | ISO_27001: 594 | - 2013 A.13.1.3 595 | NIST_800_53: 596 | - AC-4 597 | test_requirements: 598 | - id: CCC.VPC.C03.TR01 599 | text: | 600 | When a VPC peering connection is requested, the service MUST 601 | prevent connections from VPCs that are not explicitly 602 | allowed. 603 | tlp_levels: 604 | - tlp_green 605 | - tlp_amber 606 | - tlp_red 607 | link: cccvpcc03---restrict-vpc-peering-to-authorized-accounts 608 | - id: CCC.VPC.C04 609 | title: Enforce VPC Flow Logs on VPCs 610 | objective: | 611 | Ensure VPCs are configured with flow logs enabled to capture traffic 612 | information. 613 | control_family: Network Security 614 | threats: 615 | - CCC.VPC.TH04 616 | nist_csf: PR.PT-1 617 | control_mappings: 618 | CCM: 619 | - IVS-06 620 | ISO_27001: 621 | - 2013 A.12.4.1 622 | NIST_800_53: 623 | - AU-2 624 | test_requirements: 625 | - id: CCC.VPC.C04.TR01 626 | text: | 627 | When any network traffic goes to or from an interface in the VPC, 628 | the service MUST capture and log all relevant information. 629 | tlp_levels: 630 | - tlp_amber 631 | - tlp_red 632 | link: cccvpcc04---enforce-vpc-flow-logs-on-vpcs 633 | features: 634 | - id: CCC.F01 635 | title: Encryption in Transit Enabled by Default 636 | description: | 637 | Provides default encryption of data in transit through SSL or TLS. 638 | link: cccf01---encryption-in-transit-enabled-by-default 639 | - id: CCC.F02 640 | title: Encryption at Rest Enabled by Default 641 | description: | 642 | Provides default encryption of data before storage, with the option for 643 | clients to maintain control over the encryption keys. 644 | link: cccf02---encryption-at-rest-enabled-by-default 645 | - id: CCC.F03 646 | title: Access/Activity Logs 647 | description: | 648 | Provides users with the ability to track all requests made to or 649 | activities performed on resources for audit purposes. 650 | link: cccf03---access/activity-logs 651 | - id: CCC.F04 652 | title: Transaction Rate Limits 653 | description: | 654 | Allows the setting of a threshold where industry-standard throughput is 655 | achieved up to the specified rate limit. 656 | link: cccf04---transaction-rate-limits 657 | - id: CCC.F05 658 | title: Signed URLs 659 | description: | 660 | Provides the ability to grant temporary or restricted access 661 | to a resource through a custom URL that contains authentication information. 662 | link: cccf05---signed-urls 663 | - id: CCC.F06 664 | title: Identity Based Access Control 665 | description: | 666 | Provides the ability to determine access to resources based on 667 | attributes associated with a user identity. 668 | link: cccf06---identity-based-access-control 669 | - id: CCC.F07 670 | title: Event Notifications 671 | description: | 672 | Publishes events for creation, deletion, and modification of 673 | objects in a way that enables users to trigger actions in response. 674 | link: cccf07---event-notifications 675 | - id: CCC.F08 676 | title: Multi-zone Deployment 677 | description: | 678 | Provides the ability for the service to be deployed in multiple availability 679 | zones or regions to increase availability and fault tolerance. 680 | link: cccf08---multi-zone-deployment 681 | - id: CCC.F09 682 | title: Monitoring 683 | description: | 684 | Provides the ability to continuously observe, track, and analyze 685 | the performance, availability, and health of the service resources or 686 | applications. 687 | link: cccf09---monitoring 688 | - id: CCC.F10 689 | title: Logging 690 | description: | 691 | Provides the ability to transmit system events, application activities, 692 | and/or user interactions to a logging service 693 | link: cccf10---logging 694 | - id: CCC.F11 695 | title: Backup 696 | description: | 697 | Provides the ability to create copies of associated data or 698 | configurations in the form of automated backups, snapshot-based backups, 699 | and/or incremental backups. 700 | link: cccf11---backup 701 | - id: CCC.F12 702 | title: Recovery 703 | description: | 704 | Provides the ability to restore data, a system, or an application to a functional state 705 | after an incident such as data loss, corruption or a disaster. 706 | link: cccf12---recovery 707 | - id: CCC.F13 708 | title: Infrastructure as Code 709 | description: | 710 | Allows for managing and provisioning service resources 711 | through machine-readable configuration files, such as templates. 712 | link: cccf13---infrastructure-as-code 713 | - id: CCC.F14 714 | title: API Access 715 | description: | 716 | Allows users to interact programmatically with the service and its resources using APIs, SDKs and CLI. 717 | link: cccf14---api-access 718 | - id: CCC.F15 719 | title: Cost Management 720 | description: | 721 | Provides the ability to filter spending and to detect cost anomalies for the service. 722 | link: cccf15---cost-management 723 | - id: CCC.F16 724 | title: Budgeting 725 | description: | 726 | Provides the ability to trigger alerts when spending thresholds are approached or exceeded for the service. 727 | link: cccf16---budgeting 728 | - id: CCC.F17 729 | title: Alerting 730 | description: | 731 | Provides the ability to set an alarm based on performance metrics, 732 | logs, events or spending thresholds of the service. 733 | link: cccf17---alerting 734 | - id: CCC.F18 735 | title: Versioning 736 | description: | 737 | Provides the ability to maintain multiple versions of the same resource. 738 | link: cccf18---versioning 739 | - id: CCC.F19 740 | title: On-demand Scaling 741 | description: | 742 | Provide scaling of resources based on demand. 743 | link: cccf19---on-demand-scaling 744 | - id: CCC.F20 745 | title: Tagging 746 | description: | 747 | Provide the ability to tag a resource to effectively manage and gain insights of the resource. 748 | link: cccf20---tagging 749 | - id: CCC.F21 750 | title: Replication 751 | description: | 752 | Provides the ability to copy data or resource to multiple locations to ensure 753 | availability and durability. 754 | link: cccf21---replication 755 | - id: CCC.F22 756 | title: Location Lock-In 757 | description: | 758 | Provides the ability to control where the resources are created. 759 | link: cccf22---location-lock-in 760 | - id: CCC.F23 761 | title: Network Access Rules 762 | description: | 763 | Ability to control access to the resource by defining network access rules. 764 | link: cccf23---network-access-rules 765 | - id: CCC.VPC.F01 766 | title: Isolated Custom Network Creation 767 | description: | 768 | Ability to create a virtual network that is isolated from other users of the same 769 | public cloud. 770 | link: cccvpcf01---isolated-custom-network-creation 771 | - id: CCC.VPC.F02 772 | title: IPv4 CIDR Block 773 | description: | 774 | Ability to specify a IPv4 CIDR block to the virtual network. 775 | link: cccvpcf02---ipv4-cidr-block 776 | - id: CCC.VPC.F03 777 | title: IPv6 CIDR Block 778 | description: | 779 | Ability to specify a IPv6 CIDR block to the virtual network. 780 | link: cccvpcf03---ipv6-cidr-block 781 | - id: CCC.VPC.F04 782 | title: Public Subnet Creation 783 | description: | 784 | Ability to create a subnet that allows resources within the subnet to 785 | communicate with the public internet. 786 | link: cccvpcf04---public-subnet-creation 787 | - id: CCC.VPC.F05 788 | title: Private Subnet Creation 789 | description: | 790 | Ability to create a subnet that resources within the subnet cannot directly 791 | access the public internet. 792 | link: cccvpcf05---private-subnet-creation 793 | - id: CCC.VPC.F06 794 | title: Multiple Availability Zones for Subnets 795 | description: | 796 | Ability to spread the subnets in more than one availability zones. 797 | link: cccvpcf06---multiple-availability-zones-for-subnets 798 | - id: CCC.VPC.F07 799 | title: Routing Control 800 | description: | 801 | Ability to control traffic within the VPC and between the VPC and the 802 | internet or on-premises networks using customizable route tables. 803 | link: cccvpcf07---routing-control 804 | - id: CCC.VPC.F08 805 | title: Connectivity Options - Internet Gateway 806 | description: | 807 | Enables direct internet access for resources within a VPC. 808 | link: cccvpcf08---connectivity-options---internet-gateway 809 | - id: CCC.VPC.F09 810 | title: Connectivity Options - NAT Gateways 811 | description: | 812 | Allows instances in private subnets to access the internet without 813 | exposing them to inbound internet traffic. 814 | link: cccvpcf09---connectivity-options---nat-gateways 815 | - id: CCC.VPC.F10 816 | title: Connectivity Options - Private Connection 817 | description: | 818 | Dedicated, private, high-speed connections between on-premises 819 | networks and cloud VPC. 820 | link: cccvpcf10---connectivity-options---private-connection 821 | - id: CCC.VPC.F11 822 | title: Connectivity Options - VPC Peering 823 | description: | 824 | Establishing a private connection between two VPCs to 825 | communicate seamlessly. 826 | link: cccvpcf11---connectivity-options---vpc-peering 827 | - id: CCC.VPC.F12 828 | title: Connectivity Options - Transit Gateways 829 | description: | 830 | A hub-and-spoke model for connecting multiple VPCs and 831 | on-premises networks. 832 | link: cccvpcf12---connectivity-options---transit-gateways 833 | - id: CCC.VPC.F13 834 | title: Connectivity Options - Site-to-site VPN 835 | description: | 836 | Provides an encrypted connection over the internet between 837 | a VPC and an on-premises network. 838 | link: cccvpcf13---connectivity-options---site-to-site-vpn 839 | - id: CCC.VPC.F14 840 | title: Built-in DNS Resolution 841 | description: | 842 | Resolves hostnames to IP addresses for instances within the VPC 843 | allowing instances to communicate using hostnames instead of IP addresses. 844 | link: cccvpcf14---built-in-dns-resolution 845 | - id: CCC.VPC.F15 846 | title: Built-in DHCP Resolution 847 | description: | 848 | Automatically assign IP addresses, subnet masks, default gateways 849 | and other network configurations to instances within the VPC. 850 | link: cccvpcf15---built-in-dhcp-resolution 851 | - id: CCC.VPC.F16 852 | title: Flow Logs 853 | description: | 854 | Ability to capture information about the IP traffic going through the VPC. 855 | link: cccvpcf16---flow-logs 856 | - id: CCC.VPC.F17 857 | title: VPC Endpoints 858 | description: | 859 | Ability to allow secure, private connectivity between resources within a VPC 860 | and other services without the need for a public internet. 861 | link: cccvpcf17---vpc-endpoints 862 | threats: 863 | - id: CCC.TH01 864 | title: Access Control is Misconfigured 865 | description: | 866 | An attacker can exploit misconfigured access controls to grant excessive 867 | privileges or gain unauthorized access to sensitive resources. 868 | features: 869 | - CCC.F06 870 | mitre_technique: 871 | - T1078 872 | - T1548 873 | - T1203 874 | - T1098 875 | - T1484 876 | - T1546 877 | - T1537 878 | - T1567 879 | - T1048 880 | - T1485 881 | - T1565 882 | - T1027 883 | link: cccth01---access-control-is-misconfigured 884 | - id: CCC.TH02 885 | title: Data is Intercepted in Transit 886 | description: | 887 | In the event that encrypted communication is not properly in effect, an 888 | attacker can intercept traffic between clients and the service to read or 889 | modify the data during transmission. 890 | features: 891 | - CCC.F01 892 | mitre_technique: 893 | - T1557 894 | - T1040 895 | link: cccth02---data-is-intercepted-in-transit 896 | - id: CCC.TH03 897 | title: Deployment Region Network is Untrusted 898 | description: | 899 | If any part of the service is deployed in a hostile, unstable, or 900 | insecure location, an attacker may attempt to access the resource or 901 | intercept data by exploiting privileged network access or physical 902 | vulnerabilities. 903 | features: 904 | - CCC.F08 905 | mitre_technique: 906 | - T1040 907 | - T1110 908 | - T1105 909 | - T1583 910 | - T1557 911 | link: cccth03---deployment-region-network-is-untrusted 912 | - id: CCC.TH04 913 | title: Data is Replicated to Untrusted or External Locations 914 | description: | 915 | An attacker could replicate data to untrusted or external locations if replication configurations 916 | are not properly restricted. This could result in data leakage or exposure to unauthorized entities 917 | outside the organization's trusted perimeter. 918 | features: 919 | - CCC.F21 920 | mitre_technique: 921 | - T1565 922 | link: cccth04---data-is-replicated-to-untrusted-or-external-locations 923 | - id: CCC.TH05 924 | title: Data is Corrupted During Replication 925 | description: | 926 | Malicious actors may attempt to corrupt, delay, or delete data during 927 | replication processes across multiple regions or availability zones, 928 | affecting the integrity and availability of data. 929 | features: 930 | - CCC.F08 931 | - CCC.F12 932 | - CCC.F21 933 | mitre_technique: 934 | - T1485 935 | - T1565 936 | - T1491 937 | - T1490 938 | link: cccth05---data-is-corrupted-during-replication 939 | - id: CCC.TH06 940 | title: Data is Lost or Corrupted 941 | description: | 942 | Data loss or corruption can occur due to accidental deletion, 943 | misconfiguration, or malicious activity. This can result in the loss of 944 | critical data, service disruption, or unauthorized access to sensitive 945 | information. 946 | features: 947 | - CCC.F11 948 | - CCC.F18 949 | mitre_technique: 950 | - T1485 951 | - T1565 952 | - T1491 953 | - T1490 954 | link: cccth06---data-is-lost-or-corrupted 955 | - id: CCC.TH07 956 | title: Logs are Tampered With or Deleted 957 | description: | 958 | Attackers may tamper with or delete logs to cover their tracks and evade 959 | detection. This prevents security teams from identifying the full scope 960 | of an attack and may disrupt forensic investigations. 961 | features: 962 | - CCC.F03 963 | - CCC.F10 964 | mitre_technique: 965 | - T1070 966 | - T1565 967 | - T1027 968 | link: cccth07---logs-are-tampered-with-or-deleted 969 | - id: CCC.TH08 970 | title: Cost Management Data is Manipulated 971 | description: | 972 | Attackers may manipulate cost management data to hide excessive resource 973 | consumption or to deceive users about resource usage. This could be used 974 | to exhaust budgets, cause financial losses, or evade detection of other attacks. 975 | features: 976 | - CCC.F15 977 | mitre_technique: 978 | - T1565 979 | - T1070 980 | link: cccth08---cost-management-data-is-manipulated 981 | - id: CCC.TH09 982 | title: Logs or Monitoring Data are Read by Unauthorized Users 983 | description: | 984 | Unauthorized access to logs or monitoring data can provide attackers with 985 | valuable information about the system's configuration, operations, and 986 | security mechanisms. This can be used to identify vulnerabilities, plan 987 | attacks, or evade detection. 988 | features: 989 | - CCC.F03 990 | - CCC.F09 991 | mitre_technique: 992 | - T1003 993 | - T1007 994 | - T1018 995 | - T1033 996 | - T1046 997 | - T1057 998 | - T1069 999 | - T1070 1000 | - T1082 1001 | - T1120 1002 | - T1124 1003 | - T1497 1004 | - T1518 1005 | link: cccth09---logs-or-monitoring-data-are-read-by-unauthorized-users 1006 | - id: CCC.TH10 1007 | title: Alerts are Intercepted 1008 | description: | 1009 | Malicious actors may exploit event notifications to monitor and 1010 | intercept information about sensitive operations or access patterns. 1011 | features: 1012 | - CCC.F03 1013 | - CCC.F07 1014 | - CCC.F09 1015 | - CCC.F17 1016 | mitre_technique: 1017 | - T1057 1018 | - T1049 1019 | - T1083 1020 | link: cccth10---alerts-are-intercepted 1021 | - id: CCC.TH11 1022 | title: Event Notifications are Incorrectly Triggered 1023 | description: | 1024 | Malicious actors may exploit event notifications to trigger sensitive 1025 | operations or access patterns. Alternately, attackers may flood the 1026 | system with notifications to obfuscate another attack or overwhelm the 1027 | service to disrupt legitimate operations. 1028 | features: 1029 | - CCC.F07 1030 | - CCC.F17 1031 | mitre_technique: 1032 | - T1205 1033 | - T1001.001 1034 | - T1491.001 1035 | link: cccth11---event-notifications-are-incorrectly-triggered 1036 | - id: CCC.TH12 1037 | title: Resource Constraints are Exhausted 1038 | description: | 1039 | An attack or misconfiguration can consume all available resources, such 1040 | as memory, CPU, or storage, to disrupt the service or deny access to 1041 | legitimate users. This can be achieved through repeated requests, 1042 | resource-intensive operations, or the lowering of rate/budget limits. 1043 | Through auto-scaling, the attacker may also attempt to exhaust 1044 | higher-level budget thresholds to impact other systems in the same scope. 1045 | features: 1046 | - CCC.F04 1047 | - CCC.F16 1048 | - CCC.F19 1049 | mitre_technique: 1050 | - T1496 1051 | - T1499 1052 | - T1498 1053 | link: cccth12---resource-constraints-are-exhausted 1054 | - id: CCC.TH13 1055 | title: Resource Tags are Manipulated 1056 | description: | 1057 | Attackers may manipulate resource tags to alter organizational policies, 1058 | disrupt billing, or evade detection. This can result in mismanaged 1059 | resources, unauthorized access, or financial abuse. 1060 | features: 1061 | - CCC.F20 1062 | mitre_technique: 1063 | - T1565 1064 | link: cccth13---resource-tags-are-manipulated 1065 | - id: CCC.TH14 1066 | title: Older Resource Versions are Exploited 1067 | description: | 1068 | Attackers may exploit vulnerabilities in older versions of resources, 1069 | taking advantage of deprecated or insecure configurations. Without 1070 | proper version control and monitoring, outdated versions can be used 1071 | to bypass security measures. 1072 | features: 1073 | - CCC.F18 1074 | mitre_technique: 1075 | - T1027 1076 | - T1485 1077 | - T1565 1078 | - T1489 1079 | - T1562.01 1080 | - T1027 1081 | - T1485 1082 | - T1565 1083 | - T1489 1084 | link: cccth14---older-resource-versions-are-exploited 1085 | - id: CCC.TH15 1086 | title: Automated Enumeration and Reconnaissance by Non-human Entities 1087 | description: | 1088 | Attackers may deploy automated processes or bots to perform reconnaissance 1089 | activities by enumerating resources such as APIs, file systems, or directories. 1090 | These activities can help attackers identify vulnerabilities, misconfigurations, 1091 | or unsecured resources, which can then be exploited for unauthorized access 1092 | or data theft. 1093 | features: 1094 | - CCC.F14 1095 | mitre_technique: 1096 | - T1580 1097 | link: cccth15---automated-enumeration-and-reconnaissance-by-non-human-entities 1098 | - id: CCC.VPC.TH01 1099 | title: Unauthorized Access via Insecure Default Networks 1100 | description: | 1101 | Default network configurations may include insecure settings and open 1102 | firewall rules,leading to unauthorized access and potential data 1103 | breaches. 1104 | features: 1105 | - CCC.VPC.F01 1106 | mitre_technique: 1107 | - T1040 1108 | link: cccvpcth01---unauthorized-access-via-insecure-default-networks 1109 | - id: CCC.VPC.TH02 1110 | title: Exposure of Resources to Public Internet 1111 | description: | 1112 | Assignment of external IP addresses to resources exposes resources to the 1113 | public internet, increasing the risk of attacks such as brute force, 1114 | exploitation of vulnerabilities, or unauthorized access. 1115 | features: 1116 | - CCC.VPC.F04 1117 | mitre_technique: 1118 | - T1133 1119 | - T1078 1120 | link: cccvpcth02---exposure-of-resources-to-public-internet 1121 | - id: CCC.VPC.TH03 1122 | title: Unauthorized Network Access Through VPC Peering 1123 | description: | 1124 | Unauthorized VPC peering connections can allow network traffic between 1125 | untrusted or unapproved subscriptions, leading to potential data 1126 | exposure or exfiltration. 1127 | features: 1128 | - CCC.VPC.F11 1129 | mitre_technique: 1130 | - T1599 1131 | link: cccvpcth03---unauthorized-network-access-through-vpc-peering 1132 | - id: CCC.VPC.TH04 1133 | title: Lack of Network Visibility due to Disabled VPC Flow Logs 1134 | description: | 1135 | VPC subnets with disabled flow logs lack critical network traffic 1136 | visibility, which can lead to undetected unauthorized access, 1137 | data exfiltration, and network misconfigurations. This lack of 1138 | visibility increases the risk of undetected security incidents. 1139 | features: 1140 | - CCC.VPC.F16 1141 | mitre_technique: 1142 | - T1562 1143 | link: cccvpcth04---lack-of-network-visibility-due-to-disabled-vpc-flow-logs 1144 | - id: CCC.VPC.TH05 1145 | title: Overly Permissive VPC Endpoint Policies 1146 | description: | 1147 | VPC Endpoint policies that are overly permissive may inadvertently expose 1148 | resources within the VPC to unintended principals or external threats. 1149 | features: 1150 | - CCC.VPC.F17 1151 | mitre_technique: 1152 | - T1078 1153 | - T1071 1154 | link: cccvpcth05---overly-permissive-vpc-endpoint-policies 1155 | latestreleasedetails: 1156 | version: "2025.01" 1157 | assurance_level: None 1158 | threat_model_url: None 1159 | threat_model_author: None 1160 | red_team: None 1161 | red_team_exercise_url: None 1162 | release_manager: 1163 | name: Damien Burks 1164 | github_id: damienjburks 1165 | company: Citi 1166 | summary: | 1167 | This initial release is part of the first batch of control catalogs 1168 | produced by the CCC. It is the result of thousands of hours dedicated to 1169 | exploring different ways of working and collaborating, on top of time 1170 | spent researching, writing, and reviewing the content. This marks a huge 1171 | milestone for the CCC and the broader community as further releases will 1172 | continue to build on this foundation. A huge thanks to everyone who has 1173 | brought us to this point! 1174 | change_log: 1175 | - | 1176 | This initial release contains a variety of commits designed to capture 1177 | all of the features, threats, and controls for this service category. 1178 | contributors: 1179 | - name: Michael Lysaght 1180 | github_id: mlysaght2017 1181 | company: Citi 1182 | - name: Sonali Mendis 1183 | github_id: smendis-scottlogic 1184 | company: Scott Logic 1185 | - name: Eddie Knight 1186 | github_id: eddie-knight 1187 | company: Sonatype 1188 | - name: Dave Ogle 1189 | github_id: dogle-scottlogic 1190 | company: Scott Logic 1191 | - name: kazmik23 1192 | github_id: kazmik23 1193 | company: Google 1194 | --------------------------------------------------------------------------------