{"id":15021175,"url":"https://github.com/powershell/compliance","last_synced_at":"2025-07-05T03:34:37.690Z","repository":{"id":41442820,"uuid":"290908200","full_name":"PowerShell/Compliance","owner":"PowerShell","description":null,"archived":false,"fork":false,"pushed_at":"2024-02-09T22:45:24.000Z","size":80,"stargazers_count":4,"open_issues_count":7,"forks_count":16,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-29T22:22:26.567Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PowerShell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-08-28T00:01:45.000Z","updated_at":"2024-09-17T18:07:37.000Z","dependencies_parsed_at":"2024-09-18T18:04:43.807Z","dependency_job_id":null,"html_url":"https://github.com/PowerShell/Compliance","commit_stats":{"total_commits":55,"total_committers":9,"mean_commits":6.111111111111111,"dds":0.5818181818181818,"last_synced_commit":"12b724376b8717f2b8a30ad61e2a7f07cc56ef10"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PowerShell%2FCompliance","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PowerShell%2FCompliance/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PowerShell%2FCompliance/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PowerShell%2FCompliance/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PowerShell","download_url":"https://codeload.github.com/PowerShell/Compliance/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237172262,"owners_count":19266642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T19:56:13.681Z","updated_at":"2025-02-04T18:31:42.849Z","avatar_url":"https://github.com/PowerShell.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Compliance task library \u003c!-- omit in toc --\u003e\n\n**Contents of this repository are intended for use in internal Microsoft Pipelines.\nThis repository is public so the community can inspect our process and for sharing among teams.**\n\nThis repository contains Azure DevOPS YAML template for the compliance tasks needed for release products.\nThe step templates can be included in the repository using [multi-checkout](https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/multi-repo-checkout?view=azure-devops).\n\n## Table of Contents \u003c!-- omit in toc --\u003e\n\u003c!-- Used https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one to generate TOC--\u003e\n\n- [Template setup](#template-setup)\n- [Daily build Compliance template](#daily-build-compliance-template)\n- [Task templates](#task-templates)\n  - [Credential Scanner](#credential-scanner)\n  - [TermCheck AKA PoliCheck](#termcheck-aka-policheck)\n  - [ESRP Signing Template Overview](#esrp-signing-template-overview)\n    - [ESRP Authenticode minimatch example](#esrp-authenticode-minimatch-example)\n    - [ESRP Authenticode preview certificate](#esrp-authenticode-preview-certificate)\n    - [ESRP RPM example](#esrp-rpm-example)\n    - [ESRP NuPkg example](#esrp-nupkg-example)\n    - [ESRP macOS example](#esrp-macos-example)\n    - [ESRP custom signing JSON example](#esrp-custom-signing-json-example)\n    - [ESRP Custom Signing Service Connection Example](#esrp-custom-signing-service-connection-example)\n  - [ESRP Malware Scanning Template Overview](#esrp-malware-scanning-template-overview)\n    - [ESRP Scanning Custom Service Example](#esrp-scanning-custom-service-example)\n  - [Software Bill Of Materials (SBOM or Manifest) template](#software-bill-of-materials-sbom-or-manifest-template)\n\n## Template setup\n\nThe following sample shows how the templates can be included in your release YAML.\n\n1. Create a repository resource and a service connection to connect to this repository.\n\n   ```yaml\n   resources:\n     repositories:\n     - repository: ComplianceRepo\n       type: github\n       endpoint: ComplianceGHRepo\n       name: PowerShell/Compliance\n   ```\n\n1. In the compliance stage, checkout `self` repo and the `compliance` repo.\n\n    ```yaml\n    - stage: compliance\n      displayName: Compliance\n      dependsOn: Build\n      jobs:\n      - job: Compliance_Job\n          pool:\n            name: Package ES Standard Build\n          steps:\n          - checkout: self\n          - checkout: ComplianceRepo\n    ```\n\n1. Pick one of the three composed templates,\n\n    - `assembly-module-compliance.yml` - for running compliance for projects generating an assembly.\n    - `script-module-compliance.yml` - for running compliance for projects generating a script module.\n    - `ci-compliance.yml` - for running compliance as part of CI builds.\n\n1. Call the template from this repo in your yaml file and specify the values for the parameters.\n\n    ```yaml\n    - template: assembly-module-compliance.yml@C\n    - omplianceRepo\n        parameters:\n            # binskim\n            AnalyzeTarget: '$(Pipeline.Workspace)/*.dll'\n            AnalyzeSymPath: 'SRV*'\n            # component-governance\n            sourceScanPath: '$(Build.SourcesDirectory)'\n            # credscan\n            suppressionsFile: ''\n            # TermCheck AKA PoliCheck\n            targetArgument: '$(Build.SourcesDirectory)'\n            optionsUEPATH: ''\n            optionsRulesDBPath: ''\n            optionsFTPath: ''\n            # tsa-upload\n            codeBaseName: 'PSPager_202007'\n            # selections\n            APIScan: false # set to false when not using Windows APIs.\n    ```\n\n## Daily build Compliance template\n\nThis example add the template for a daily build.\nIt will automatically skip for PRs.\nIt should be put near the end of the job.\n\n```yaml\n  - template: dailyBuildCompliance.yml@ComplianceRepo\n    parameters:\n      sourceScanPath: '$(repoPath)'\n```\n\n## Task templates\n\n### Credential Scanner\n\nThe Credential Scanner can be configured to ignore paths (including folders),\nwith a JSON file (usually stored at `tools/credScan/suppress.json`):\n\n```json\n{\n  \"tool\": \"Credential Scanner\",\n  \"suppressions\": [\n    {\n      \"folder\": \"node_modules\",\n      \"_justification\": \"Third-party code must not be scanned\"\n    },\n    {\n      \"file\": \"Cert.pfx\",\n      \"_justification\": \"Test certificate with private key\"\n    }\n  ]\n}\n```\n\nThen supply the path to this file in your repo as the `suppresionsFile`\nparameter. Enabling folders is only supported by running this tool in \"debug\"\nmode, so be aware of and ignore this warning given by the task:\n\n\u003e [WARNING] Running in DebugMode! Result file is *NOT* to be treated as OFFICIAL!\n\n### TermCheck AKA PoliCheck\n\nThe term checker is setup to recursively scan the given folder at\n`targetArgument`. Because the use these templates necessitates multi-repo\ncheckout, you will likely want to supply the path to your specific sources, e.g.\n`targetArgument: '$(Build.SourcesDirectory)/my-repo-name'`.\n\nUser exclusions can be specified in an XML file at the path given with the\nparameter `optionsUEPATH`. An example (usually stored at\n`tools/terms/UserExclusions.xml`) looks like:\n\n```xml\n\u003cPoliCheckExclusions\u003e\n  \u003c!-- All strings must be UPPER CASE --\u003e\n  \u003c!--Each of these exclusions is a folder name -if \\[name]\\exists in the file path, it will be skipped --\u003e\n  \u003c!--\u003cExclusion Type=\"FolderPathFull\"\u003eABC|XYZ\u003c/Exclusion\u003e--\u003e\n  \u003cExclusion Type=\"FolderPathFull\"\u003e.GIT|NODE_MODULES\u003c/Exclusion\u003e\n  \u003c!--Each of these exclusions is a folder name -if any folder or file starts with \"\\[name]\", it will be skipped --\u003e\n  \u003c!--\u003cExclusion Type=\"FolderPathStart\"\u003eABC|XYZ\u003c/Exclusion\u003e--\u003e\n  \u003c!--Each of these file types will be completely skipped for the entire scan --\u003e\n  \u003c!--\u003cExclusion Type=\"FileType\"\u003e.ABC|.XYZ\u003c/Exclusion\u003e--\u003e\n  \u003c!--The specified file names will be skipped during the scan regardless which folder they are in --\u003e\n  \u003c!--\u003cExclusion Type=\"FileName\"\u003eABC.TXT|XYZ.CS\u003c/Exclusion\u003e--\u003e\n\u003c/PoliCheckExclusions\u003e\n```\n\nThe paths given _must_ be upper case as the tool upper cases all paths before\ndoing its comparison. Multiple patterns of the same exclusion type _must_ be\nspecified with the \"or\" operator: `|`, not with multiple XML tags.\n\nSee the internal [wiki](https://www.1eswiki.com/wiki/PoliCheck_Build_Task) for\nmore information about this ADO task.\n\n### ESRP Signing Template Overview\n\n**Requires on-boarding**, see the wiki in the internal PowerShell Maintainers teams channel.\n\nMake sure to create the variable group named `ESRP` and make it available to the pipeline.\nDetails can be found in the PowerShell Maintainers teams channel's Wiki tab.\n\n1. Call the template from this repo in your yaml file and specify the values for the parameters.\n\n```yaml\n- template: EsrpSign.yml@ComplianceRepo\n    parameters:\n        # the folder which contains the binaries to sign\n        buildOutputPath: $(signSrcPath)\n        # the location to put the signed output.\n        # Note, All files in \"buildOutputPath\" are copied to \"signOutputPath\" not just ones matching the \"pattern\".\n        signOutputPath: $(signOutPath)\n        # the certificate ID to use\n        certificateId: \"CP-230012\"\n        # The file pattern to use\n        # If not using minimatch: comma separated, with * supported\n        # If using minimatch: newline separated, with !, **, and * supported.\n        # See link in the useMinimatch comments.\n        pattern: '*.dll,*.psd1,*.psm1,*.ps1xml,*.mof'\n        # decides if the task should use minimatch for the pattern matching.\n        # https://github.com/isaacs/minimatch#features\n        useMinimatch: false\n        # If \"true\", use a custom JSON string for ESRP signing. Defaults to \"false\".\n        useCustomEsrpJson: false\n        # If \"true\", ESRP will automatically verify your files are signed properly (eg signtool /verify).\n        # Only supported for authenticode \u0026 nuget signing.\n        # Defaults to \"false\".\n        verifySignature: false\n        # If \"true\", ESRP will page hash sign your files.\n        # Only supported for authenticode signing.\n        # Defaults to \"true\".\n        pageHash: true\n        # If \"true\", ESRP will be called to sign your files.\n        # If \"false\", ESRP is not called, files will not be signed.\n        # If \"auto\", ESRP is called if and only certain build conditions are met.\n        # Defaults to \"auto\".\n        shouldSign: 'auto'\n        # If \"true\", your files are always copied to signOutputPath even if ESRP is not called to sign the files.\n        # Useful to set to true if you want your build pipeline to behave as close to 'normal' as possible when testing and not signing.\n        # Defaults to \"false\".\n        alwaysCopy: false\n        # The name of the Azure DevOps Service connection you configured for ESRP Signing.\n        # Defaults to \"pwshSigning\".\n        signingService: 'pwshSigning'\n\n```\n\n#### ESRP Authenticode minimatch example\n\nThis example signs `dll` and `psm1` files recursively and `psd1` files in the root of the `buildOutputPath`, using minimatch.\n\nFor full features see:  https://github.com/isaacs/minimatch#features\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        certificateId: \"CP-230012\"\n        pattern: |\n          **\\*.dll\n          *.psd1\n          **\\*.psm1\n        useMinimatch: true\n```\n\n#### ESRP Authenticode preview certificate\n\nThis example signs `dll` and `psm1` files recursively and `psd1` files in the root of the `buildOutputPath`, using minimatch.\n\nFor full features see:  https://github.com/isaacs/minimatch#features\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        certificateId: \"CP-460906\"\n        pattern: |\n          **\\*.dll\n          *.psd1\n          **\\*.psm1\n        useMinimatch: true\n```\n\n#### ESRP RPM example\n\nThis example signs `dll` `psd1` and `psm1` files recursively, using minimatch.\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        # this is the cert for RPM signing\n        certificateId: \"CP-450779-Pgp\"\n        # this is the pattern for RPM signing\n        pattern: |\n            **\\*.rpm\n        useMinimatch: true\n```\n\n#### ESRP NuPkg example\n\nThis example signs `dll` `psd1` and `psm1` files recursively, using minimatch.\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        # this is the cert for NuPkg signing\n        certificateId: \"CP-401405\"\n        # this is the pattern for NuPkg signing\n        pattern: |\n            **\\*.nupkg\n        useMinimatch: true\n```\n\n#### ESRP macOS example\n\nThis example signs `pkg` files recursively, using minimatch.\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        # this is the cert for macOS signing\n        certificateId: \"CP-401337-Apple\"\n        # this is the pattern for pkg signing\n        pattern: |\n            **\\*.pkg\n        useMinimatch: true\n```\n\n#### ESRP custom signing JSON example\n\n1. Set the build variable `ESRP_TEMPLATE_CUSTOM_JSON` to your desired ESRP JSON string.\n2. Call EsrpSign.yml@ComplianceRepo with certificateId: \"\" and useCustomEsrpJson: true.\n\n```yaml\n- pwsh: |\n    [string] $SigningServer = '$(SigningServer)'\n    Write-Verbose \"SigningServer - $SigningServer\" -Verbose\n\n    $esrpParameters = @{\n      OpusName   = \"Microsoft\"\n      OpusInfo   = \"http://www.microsoft.com\"\n      FileDigest = \"/fd sha256\"\n      TimeStamp  = \"/tr \"\"$SigningServer\"\" /td sha256\"\n    }\n\n    $esrp = @(\n      @{\n        KeyCode = \"Dynamic\"\n        CertTemplateName = \"WINMSAPP1ST\"\n        CertSubjectName = \"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\"\n        operationCode = \"SigntoolSign\"\n        Parameters = $esrpParameters\n        ToolName = \"sign\"\n        ToolVersion = \"1.0\"},\n      @{\n        KeyCode = \"Dynamic\"\n        CertTemplateName = \"WINMSAPP1ST\"\n        CertSubjectName = \"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US\"\n        OperationCode = \"SigntoolVerify\"\n        ToolName = \"sign\"\n        ToolVersion = \"1.0\"\n      }\n    )\n\n    $vstsCommandString = \"vso[task.setvariable variable=ESRP_TEMPLATE_CUSTOM_JSON][$($esrp | ConvertTo-Json -Compress)]\"\n    Write-Verbose -Message (\"sending \" + $vstsCommandString) -Verbose\n    Write-Host \"##$vstsCommandString\"\n  displayName: Generate app signing JSON\n\n- template: EsrpSign.yml@ComplianceRepo\n    parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        # Explicitly set to \"\" for custom string\n        certificateId: \"\"\n        pattern: '*.msix'\n        useMinimatch: false\n        # Use ESRP_TEMPLATE_CUSTOM_JSON as custom string\n        useCustomEsrpJson: true\n```\n\n#### ESRP Custom Signing Service Connection Example\n\nThis example uses a custom signing (Azure DevOps) service connection name.\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        certificateId: \"CP-230012\"\n        pattern: '*.dll'\n        # The name of the Azure DevOps Service connection you configured for ESRP Signing.\n        # Defaults to \"pwshSigning\".\n        signingService: 'FactoryOrchestratorSigning'\n\n```\n\n### ESRP Malware Scanning Template Overview\n\n**Requires on-boarding**, see the wiki in the internal PowerShell Maintainers teams channel.\n\nDetails can be found in the PowerShell Maintainers teams channel's Wiki tab.\n\nThis should be use in multi-Job builds when you are uploading unsigned binaries.\nFiles are automatically scanned on signing,\nscanning on each upload will allow us to detect when any malware was introduced.\n\nThis should be use in multi-Job builds when you are uploading unsigned binaries.\nFiles are automatically scanned on signing,\nscanning on each upload will allow us to detect when any malware was introduced.\n\n1. Call the template from this repo in your yaml file and specify the values for the parameters.\n\n```yaml\n\n  - template: EsrpScan.yml@ComplianceRepo\n    parameters:\n        # the path with the files to scan\n        scanPath: $(System.ArtifactsDirectory)\n        # the minimatch pattern to find the files\n        # https://github.com/isaacs/minimatch#features\n        pattern: |\n          **\\*.rpm\n          **\\*.deb\n          **\\*.tar.gz\n        # The name of the Azure DevOps Service connection you configured for ESRP Malware Scanning.\n        # Defaults to \"pwshEsrpScanning\".\n        scanningService: 'pwshEsrpScanning'\n```\n\n#### ESRP Scanning Custom Service Example\n\nThis example uses a custom ESRP malware scanning (Azure DevOps) service name.\n\n```yaml\n  - template: EsrpSign.yml@ComplianceRepo\n      parameters:\n        buildOutputPath: $(signSrcPath)\n        signOutputPath: $(signOutPath)\n        certificateId: \"CP-230012\"\n        pattern: |\n          **\\*.dll\n        scanningService: 'FactoryOrchestratorScanning'\n\n```\n\n### Software Bill Of Materials (SBOM or Manifest) template\n\nThis should be done after the build is done and all files are generated,\nbut you have not packaged yet.\n\n```yaml\n  - template: Sbom.yml@ComplianceRepo\n    parameters:\n      BuildDropPath: '$(System.ArtifactsDirectory)/dotnetPublishOutput'\n      Build_Repository_Uri: 'https://github.com/powershell/powershell.git'\n      displayName: PowerShell SBOM\n      packageName: PowerShell Windows x64\n      packageVersion: 7.2.1\n      # Optional - Path to scan for components or CGManifest.json\n      # Same as source scan path for Component Governance\n      # sourceScanPath: \u003cfolderPath\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpowershell%2Fcompliance","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpowershell%2Fcompliance","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpowershell%2Fcompliance/lists"}