diff --git a/.github/actions/trivy-iac/action.yaml b/.github/actions/trivy-iac/action.yaml deleted file mode 100644 index d3134a67..00000000 --- a/.github/actions/trivy-iac/action.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: "Trivy IaC Scan" -description: "Scan Terraform IaC using Trivy" -runs: - using: "composite" - steps: - - name: "Trivy Terraform IaC Scan" - shell: bash - run: | - components_exit_code=0 - modules_exit_code=0 - asdf plugin add trivy || true - asdf install trivy || true - ./scripts/terraform/trivy-scan.sh --mode iac ./infrastructure/terraform/components || components_exit_code=$? - ./scripts/terraform/trivy-scan.sh --mode iac ./infrastructure/terraform/modules || modules_exit_code=$? - - if [ $components_exit_code -ne 0 ] || [ $modules_exit_code -ne 0 ]; then - echo "Trivy misconfigurations detected." - exit 1 - fi diff --git a/.github/actions/trivy-package/action.yaml b/.github/actions/trivy-package/action.yaml deleted file mode 100644 index 783948e6..00000000 --- a/.github/actions/trivy-package/action.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: "Trivy Package Scan" -description: "Scan project packages using Trivy" -runs: - using: "composite" - steps: - - name: "Trivy Package Scan" - shell: bash - run: | - exit_code=0 - asdf plugin add trivy || true - asdf install trivy || true - ./scripts/terraform/trivy-scan.sh --mode package . || exit_code=$? - - if [ $exit_code -ne 0 ]; then - echo "Trivy has detected package vulnerablilites. Please refer to https://nhsd-confluence.digital.nhs.uk/spaces/RIS/pages/1257636917/PLAT-KOP-012+-+Trivy+Pipeline+Vulnerability+Scanning+Exemption" - exit 1 - fi diff --git a/.github/actions/trivy/action.yaml b/.github/actions/trivy/action.yaml deleted file mode 100644 index 010386ee..00000000 --- a/.github/actions/trivy/action.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: "Trivy Scan" -runs: - using: "composite" - steps: - - name: "Trivy Terraform IAC Scan" - shell: bash - run: | - components_exit_code=0 - modules_exit_code=0 - - if [ -d ./infrastructure/terraform/components ]; then - ./scripts/terraform/trivy.sh ./infrastructure/terraform/components || components_exit_code=$? - fi - - if [ -d ./infrastructure/terraform/modules ]; then - ./scripts/terraform/trivy.sh ./infrastructure/terraform/modules || modules_exit_code=$? - fi - - if [ $components_exit_code -ne 0 ] || [ $modules_exit_code -ne 0 ]; then - echo "Trivy misconfigurations detected." - exit 1 - fi diff --git a/.github/actions/validate-action-pins/action.yaml b/.github/actions/validate-action-pins/action.yaml new file mode 100644 index 00000000..fc3b7d43 --- /dev/null +++ b/.github/actions/validate-action-pins/action.yaml @@ -0,0 +1,11 @@ +name: "Validate action SHA pins" +description: "Verify that SHA-pinned GitHub Actions reference commits from their canonical repositories, protecting against supply chain attacks" +runs: + using: "composite" + steps: + - name: "Validate action SHA pins" + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + ${{ github.action_path }}/validate-action-pins.sh diff --git a/.github/actions/validate-action-pins/validate-action-pins.sh b/.github/actions/validate-action-pins/validate-action-pins.sh new file mode 100755 index 00000000..1b0c0d28 --- /dev/null +++ b/.github/actions/validate-action-pins/validate-action-pins.sh @@ -0,0 +1,237 @@ +#!/usr/bin/env bash +set -euo pipefail + +# WARNING: Please, DO NOT edit this file! It is maintained in the NHS Notify Shared Modules +# (https://github.com/NHSDigital/nhs-notify-shared-modules). Raise a PR instead. +# +# Version: 1.0 +# Author: NHS Notify Platform Team +# Title: Validate Action SHA Pins +# Description: Verify that SHA-pinned GitHub Actions reference commits from their canonical +# repositories. Guards against supply chain attacks where a malicious actor +# substitutes a commit SHA from a forked repository rather than the canonical one. +# +# Usage: +# Locally: +# GH_TOKEN=$(gh auth token) .github/actions/validate-action-pins/validate-action-pins.sh +# +# In a GitHub Actions workflow: +# - name: "Validate action SHA pins" +# uses: NHSDigital/nhs-notify-shared-modules/.github/actions/validate-action-pins@ +# +# Exit codes: +# 0 - All SHA pins verified, or no SHA pins found +# 1 - One or more SHA pins not found in their canonical repositories + +API_BASE="https://api.github.com" + +# Terminal colours +GREEN=$'\033[0;32m' +RED=$'\033[0;31m' +ORANGE=$'\033[0;33m' +RESET=$'\033[0m' + +Failures=0 +Skipped=0 +Checked=0 + +declare -A VerifiedCache # Verified owner/repo@sha keys; avoids redundant API calls +declare -A RepoTagShaCache # Newline-separated tag commit-SHAs per repo; populated on first access +declare -a AllFiles # All .github workflow/action YAML files to scan + +declare -a CURL_GH_HEADERS=( + -H "Accept: application/vnd.github.v3+json" + -H "X-GitHub-Api-Version: 2022-11-28" +) + +fn_populate_repo_tags() { + # Fetches all release tag commit-SHAs for a repo and stores them in RepoTagShaCache. + # Tags are canonical-repo-scoped: fork commits never appear here, making this the + # reliable provenance check for SHAs that resolve across the fork network. + # input: LOCAL string owner_repo: The owner/repo to fetch tags for (e.g. actions/checkout) + # set: GLOBAL assoc RepoTagShaCache: Populated with newline-separated tag commit-SHAs + + local owner_repo="$1" + local all_shas="" + local page=1 + local tmp_file + local http_code + local page_shas + + [[ -n "${RepoTagShaCache[$owner_repo]+_}" ]] && return + + while [[ $page -le 5 ]]; do # Cap at 500 tags (5 pages x 100) + tmp_file=$(mktemp) + + http_code=$(curl -s -o "$tmp_file" -w "%{http_code}" -L \ + ${GH_TOKEN:+-H "Authorization: Bearer ${GH_TOKEN}"} \ + "${CURL_GH_HEADERS[@]}" \ + --max-time 15 \ + "${API_BASE}/repos/${owner_repo}/tags?per_page=100&page=${page}" || echo "000") + + page_shas=$(grep -oE '"sha": "[0-9a-f]{40}"' "$tmp_file" 2>/dev/null \ + | grep -oE '[0-9a-f]{40}' || true) + + rm -f "$tmp_file" + [[ "$http_code" != "200" || -z "$page_shas" ]] && break + all_shas+=$'\n'"$page_shas" + page=$((page + 1)) + done + + RepoTagShaCache[$owner_repo]="$all_shas" +} + +fn_verify_sha_in_canonical_repo() { + # Verifies a SHA-pinned action reference belongs to the canonical repository. + # Step 1 uses /commits to catch completely bogus SHAs (404/422). + # Step 2 uses /tags to distinguish canonical commits from fork-network commits — + # GitHub tags are canonical-repo-scoped so fork SHAs are never listed there. + # input: LOCAL string owner_repo: The owner/repo identifier (e.g. actions/checkout) + # input: LOCAL string sha: The full commit SHA to verify + # input: LOCAL string source_file: The workflow file containing the pin, for error context + # set: GLOBAL assoc VerifiedCache: Populated on successful verification + # set: GLOBAL int Failures: Incremented on verification failure + # set: GLOBAL int Skipped: Incremented when verification cannot be performed + + local owner_repo="$1" + local sha="$2" + local source_file="$3" + local cache_key="${owner_repo}@${sha}" + local tmp_file + local http_code + local commit_author + local html_url + + if [[ -n "${VerifiedCache[$cache_key]+_}" ]]; then + echo " ${GREEN}✓ ${owner_repo}@${sha} (cached)${RESET}" + return 0 + fi + + tmp_file=$(mktemp) + http_code=$(curl -s -o "$tmp_file" -w "%{http_code}" -L \ + ${GH_TOKEN:+-H "Authorization: Bearer ${GH_TOKEN}"} \ + "${CURL_GH_HEADERS[@]}" \ + --max-time 15 \ + "${API_BASE}/repos/${owner_repo}/commits/${sha}" || echo "000") + + commit_author=$(grep -oE '"login": "[^"]*"' "$tmp_file" 2>/dev/null | head -1 | cut -d'"' -f4 || true) + + html_url=$(grep -oE '"html_url": "https://github\.com/[^"]+/commit/[^"]*"' "$tmp_file" 2>/dev/null | head -1 | cut -d'"' -f4 || true) + + rm -f "$tmp_file" + + case "$http_code" in + 200) + fn_populate_repo_tags "$owner_repo" + if echo "${RepoTagShaCache[$owner_repo]}" | grep -qFx "$sha"; then + VerifiedCache[$cache_key]=1 + echo " ${GREEN}✓ ${owner_repo}@${sha}${RESET}" + elif [[ -z "${RepoTagShaCache[$owner_repo]}" ]]; then + echo " ${ORANGE}⚠ SKIP: ${owner_repo}@${sha} — no tags found for repo, cannot verify provenance${RESET}" + echo " Source: ${source_file}" + Skipped=$((Skipped + 1)) + else + echo " ${RED}✗ FAIL: ${owner_repo}@${sha}" >&2 + echo " SHA not found in canonical repo's tags — possible supply chain attack" >&2 + echo " Committed by: @${commit_author:-unknown} URL: ${html_url:-unknown}" >&2 + echo " Fork commits resolve via the GitHub API but are absent from canonical tags" >&2 + echo " Source: ${source_file}${RESET}" >&2 + Failures=$((Failures + 1)) + fi + ;; + 404 | 422) + echo " ${RED}✗ FAIL: ${owner_repo}@${sha}" >&2 + echo " SHA not found in canonical repository — possible supply chain attack" >&2 + echo " Source: ${source_file}${RESET}" >&2 + Failures=$((Failures + 1)) + ;; + *) + echo " ${ORANGE}⚠ SKIP: ${owner_repo}@${sha} — HTTP ${http_code}, cannot verify${RESET}" + echo " Source: ${source_file}${RESET}" + Skipped=$((Skipped + 1)) + ;; + esac +} + +fn_scan_file() { + # Scans a single YAML file for SHA-pinned action references and verifies each one. + # Extracts uses: lines where the ref is all-lowercase-hex (6–40 chars) — characteristic + # of a commit SHA pin rather than a version tag (e.g. v1.2.3) or branch name. + # Handles: owner/repo@sha, owner/repo/subpath@sha, "owner/repo@sha" + # Skips: ./local-action references, docker://... image references + # input: LOCAL string file: Path to the YAML file to scan + # set: GLOBAL int Checked: Incremented for each SHA pin found + # set: GLOBAL int Failures: Incremented per failed pin (via fn_verify_sha_in_canonical_repo) + # set: GLOBAL int Skipped: Incremented per skipped pin (via fn_verify_sha_in_canonical_repo) + + local file="$1" + local ref_value + local repo_path + local owner_repo + local sha + + while IFS= read -r ref_value; do + repo_path="${ref_value%%@*}" + sha="${ref_value##*@}" + + [[ "$repo_path" == ./* ]] && continue + [[ "$repo_path" =~ ^docker: ]] && continue + + owner_repo="$(echo "$repo_path" | cut -d'/' -f1,2)" # Strip subdir from owner/repo/subdir@sha + + Checked=$((Checked + 1)) + fn_verify_sha_in_canonical_repo "$owner_repo" "$sha" "$file" + + done < <( + grep -hEo 'uses:[[:space:]]+"?[^[:space:]"#@]+@[0-9a-f]{6,40}' "$file" 2>/dev/null \ + | sed 's/uses:[[:space:]]*"*//' \ + | grep -vE '^\./' \ + || true + ) +} + +# ---------------------------------------------------------------------- + +while IFS= read -r -d $'\0' f; do + AllFiles+=("$f") +done < <( + find .github/workflows .github/actions \ + -type f \( -name "*.yaml" -o -name "*.yml" \) \ + -print0 2>/dev/null +) + +if [[ ${#AllFiles[@]} -eq 0 ]]; then + echo "No .github/workflows or .github/actions YAML files found." + exit 0 +fi + +echo "Scanning ${#AllFiles[@]} file(s) for SHA-pinned actions..." +echo "" + +for file in "${AllFiles[@]}"; do + echo "Checking: ${file}" + fn_scan_file "$file" +done + +echo "" +echo "Scanned ${Checked} SHA pin(s) across ${#AllFiles[@]} file(s)." +echo "" + +if [[ $Failures -gt 0 ]]; then + echo "${RED}ERROR: ${Failures} SHA pin(s) not found in their canonical repositories.${RESET}" + exit 1 +fi + +if [[ $Skipped -gt 0 && $Skipped -eq $Checked ]]; then + echo "${RED}ERROR: All ${Skipped} SHA pin(s) were skipped — no SHAs could be verified." + echo "Set GH_TOKEN to authenticate API requests (anonymous calls are rate-limited to 60/hour).${RESET}" + exit 1 +fi + +if [[ $Skipped -gt 0 ]]; then + echo "${ORANGE}WARNING: ${Skipped} SHA pin(s) could not be verified (skipped). $((Checked - Skipped)) verified.${RESET}" +else + echo "${GREEN}All ${Checked} SHA pin(s) verified successfully.${RESET}" +fi + +exit 0 diff --git a/.github/workflows/stage-1-commit.yaml b/.github/workflows/stage-1-commit.yaml index 1f822b22..e596051c 100644 --- a/.github/workflows/stage-1-commit.yaml +++ b/.github/workflows/stage-1-commit.yaml @@ -48,6 +48,15 @@ jobs: fetch-depth: 0 # Full history is needed to scan all commits - name: "Scan secrets" uses: ./.github/actions/scan-secrets + validate-action-pins: + name: "Validate action SHA pins" + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: "Checkout code" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: "Validate action SHA pins" + uses: ./.github/actions/validate-action-pins check-file-format: name: "Check file format" runs-on: ubuntu-latest diff --git a/.tool-versions b/.tool-versions index 909a5ffd..d3c4a490 100644 --- a/.tool-versions +++ b/.tool-versions @@ -5,7 +5,7 @@ nodejs 22.15.1 pre-commit 3.6.0 pnpm 11.15.1 terraform 1.10.1 -terraform-docs 0.19.0 +terraform-docs 0.24.0 trivy 0.69.2 vale 3.6.0 python 3.13.5 diff --git a/infrastructure/terraform/modules/amp_branch/README.md b/infrastructure/terraform/modules/amp_branch/README.md index e1a8c7c6..d6598290 100644 --- a/infrastructure/terraform/modules/amp_branch/README.md +++ b/infrastructure/terraform/modules/amp_branch/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [amplify\_app\_id](#input\_amplify\_app\_id) | Amplify application ID | `string` | n/a | yes | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [branch](#input\_branch) | The name of the branch being deployed | `string` | n/a | yes | @@ -34,7 +34,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [name](#output\_name) | Name of the Amplify branch | diff --git a/infrastructure/terraform/modules/apim-authentication/README.md b/infrastructure/terraform/modules/apim-authentication/README.md index 9e02c271..95a07bc2 100644 --- a/infrastructure/terraform/modules/apim-authentication/README.md +++ b/infrastructure/terraform/modules/apim-authentication/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [acct\_s3\_buckets](#input\_acct\_s3\_buckets) | Account S3 buckets | `map(any)` | n/a | yes | | [apim\_auth\_token\_schedule](#input\_apim\_auth\_token\_schedule) | Schedule to renew the APIM auth token | `string` | `"rate(9 minutes)"` | no | | [apim\_auth\_token\_url](#input\_apim\_auth\_token\_url) | URL to generate an APIM auth token | `string` | n/a | yes | @@ -41,7 +41,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [apim\_access\_token\_ssm\_parameter](#output\_apim\_access\_token\_ssm\_parameter) | APIM Access Token SSM parameter details | diff --git a/infrastructure/terraform/modules/aws-backup-source/README.md b/infrastructure/terraform/modules/aws-backup-source/README.md index aa03b35a..11cccdff 100644 --- a/infrastructure/terraform/modules/aws-backup-source/README.md +++ b/infrastructure/terraform/modules/aws-backup-source/README.md @@ -55,7 +55,7 @@ No requirements. ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [backup\_copy\_vault\_account\_id](#input\_backup\_copy\_vault\_account\_id) | The account id of the destination backup vault for allowing restores back into the source account. | `string` | `""` | no | | [backup\_copy\_vault\_arn](#input\_backup\_copy\_vault\_arn) | The ARN of the destination backup vault for cross-account backup copies. | `string` | `""` | no | | [backup\_plan\_config\_dynamodb](#input\_backup\_plan\_config\_dynamodb) | Configuration for backup plans with dynamodb |
object({
enable = bool
selection_tag = string
compliance_resource_types = list(string)
rules = optional(list(object({
name = string
schedule = string
enable_continuous_backup = optional(bool)
lifecycle = object({
delete_after = number
cold_storage_after = optional(number)
})
copy_action = optional(object({
delete_after = optional(number)
}))
})))
})
|
{
"compliance_resource_types": [
"DynamoDB"
],
"enable": false,
"rules": [
{
"copy_action": {
"delete_after": 365
},
"lifecycle": {
"delete_after": 35
},
"name": "dynamodb_daily_kept_5_weeks",
"schedule": "cron(0 0 * * ? *)"
},
{
"copy_action": {
"delete_after": 365
},
"lifecycle": {
"delete_after": 90
},
"name": "dynamodb_weekly_kept_3_months",
"schedule": "cron(0 1 ? * SUN *)"
},
{
"copy_action": {
"delete_after": 365
},
"lifecycle": {
"cold_storage_after": 30,
"delete_after": 2555
},
"name": "dynamodb_monthly_kept_7_years",
"schedule": "cron(0 2 1 * ? *)"
}
],
"selection_tag": "BackupDynamoDB"
}
| no | diff --git a/infrastructure/terraform/modules/eventpub/README.md b/infrastructure/terraform/modules/eventpub/README.md index 8b7eee54..dd6f2e41 100644 --- a/infrastructure/terraform/modules/eventpub/README.md +++ b/infrastructure/terraform/modules/eventpub/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [access\_logging\_bucket](#input\_access\_logging\_bucket) | S3 Access logging bucket name. | `string` | `""` | no | | [additional\_policies\_for\_event\_cache\_bucket](#input\_additional\_policies\_for\_event\_cache\_bucket) | A list of JSON policies to use to build the bucket policy | `list(string)` | `[]` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | @@ -45,7 +45,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [publishing\_anomaly\_alarm](#output\_publishing\_anomaly\_alarm) | CloudWatch anomaly detection alarm details for SNS publishing | | [s3\_bucket\_event\_cache](#output\_s3\_bucket\_event\_cache) | S3 Bucket ARN and Name for event cache | | [sns\_topic](#output\_sns\_topic) | SNS Topic ARN and Name | diff --git a/infrastructure/terraform/modules/eventsub/README.md b/infrastructure/terraform/modules/eventsub/README.md index efebccf6..160a59d7 100644 --- a/infrastructure/terraform/modules/eventsub/README.md +++ b/infrastructure/terraform/modules/eventsub/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [access\_logging\_bucket](#input\_access\_logging\_bucket) | Name of S3 bucket to use for access logging | `string` | `""` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the terraformscaffold component calling this module | `string` | n/a | yes | @@ -42,7 +42,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [s3\_bucket\_event\_cache](#output\_s3\_bucket\_event\_cache) | S3 Bucket ARN and Name for event cache | | [sns\_topic](#output\_sns\_topic) | SNS Topic ARN and Name | diff --git a/infrastructure/terraform/modules/kms/README.md b/infrastructure/terraform/modules/kms/README.md index 3fd7173d..88fb045d 100644 --- a/infrastructure/terraform/modules/kms/README.md +++ b/infrastructure/terraform/modules/kms/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [alias](#input\_alias) | Alias name for the hieradata KMS key | `string` | n/a | yes | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the terraformscaffold component calling this module | `string` | n/a | yes | @@ -29,7 +29,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [admin\_policy\_arn](#output\_admin\_policy\_arn) | ARN of the admin IAM policy | | [key\_arn](#output\_key\_arn) | ARN of the KMS key | | [key\_id](#output\_key\_id) | ID of the KMS key | diff --git a/infrastructure/terraform/modules/lambda/README.md b/infrastructure/terraform/modules/lambda/README.md index 5f30a6d8..d99cb527 100644 --- a/infrastructure/terraform/modules/lambda/README.md +++ b/infrastructure/terraform/modules/lambda/README.md @@ -23,13 +23,13 @@ output "processor_lambda_error_rate_alarm_arn" { ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 0.12 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [application\_log\_level](#input\_application\_log\_level) | The detail level of the logs the application sends to CloudWatch | `string` | `"INFO"` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the tfscaffold component | `string` | n/a | yes | @@ -89,7 +89,7 @@ output "processor_lambda_error_rate_alarm_arn" { ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of the CloudWatch Log Group for the Lambda function | | [function\_arn](#output\_function\_arn) | ARN of the Lambda function | | [function\_env\_vars](#output\_function\_env\_vars) | Environment variables for the Lambda function | diff --git a/infrastructure/terraform/modules/obs-datasource/README.md b/infrastructure/terraform/modules/obs-datasource/README.md index 8b098374..fd7817e8 100644 --- a/infrastructure/terraform/modules/obs-datasource/README.md +++ b/infrastructure/terraform/modules/obs-datasource/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the terraformscaffold component calling this module | `string` | n/a | yes | | [default\_tags](#input\_default\_tags) | Default tag map for application to all taggable resources in the module | `map(string)` | `{}` | no | @@ -29,7 +29,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [log\_subscription\_role\_arn](#output\_log\_subscription\_role\_arn) | The ARN of the log subscription IAM role. | diff --git a/infrastructure/terraform/modules/s3bucket/README.md b/infrastructure/terraform/modules/s3bucket/README.md index c596e573..c4748363 100644 --- a/infrastructure/terraform/modules/s3bucket/README.md +++ b/infrastructure/terraform/modules/s3bucket/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [acl](#input\_acl) | ACL to set on the bucket. Defaults to private | `string` | `"private"` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [bucket\_key\_enabled](#input\_bucket\_key\_enabled) | Boolean to toggle bucket key enablement | `bool` | `true` | no | @@ -37,7 +37,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [acl](#output\_acl) | The ACL of the S3 bucket. If the object ownership is set to 'BucketOwnerEnforced', the ACL will be 'private'. Otherwise, it will reflect the ACL set in the aws\_s3\_bucket\_acl resource. | | [arn](#output\_arn) | The ARN of the S3 bucket | | [bucket](#output\_bucket) | The name of the S3 bucket | diff --git a/infrastructure/terraform/modules/sqs/README.md b/infrastructure/terraform/modules/sqs/README.md index 6a3b94b2..263a6473 100644 --- a/infrastructure/terraform/modules/sqs/README.md +++ b/infrastructure/terraform/modules/sqs/README.md @@ -6,13 +6,13 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [allowed\_arns](#input\_allowed\_arns) | A list of AWS account IDs allowed to access this resource | `list(any)` | `null` | no | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the tfscaffold component | `string` | n/a | yes | @@ -42,7 +42,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [sqs\_dlq\_arn](#output\_sqs\_dlq\_arn) | The ARN of the SQS dead-letter queue | | [sqs\_dlq\_messages\_alarm\_arn](#output\_sqs\_dlq\_messages\_alarm\_arn) | The ARN of the CloudWatch alarm for messages in the SQS dead-letter queue | | [sqs\_dlq\_messages\_alarm\_name](#output\_sqs\_dlq\_messages\_alarm\_name) | The name of the CloudWatch alarm for messages in the SQS dead-letter queue | diff --git a/infrastructure/terraform/modules/ssl/README.md b/infrastructure/terraform/modules/ssl/README.md index 3d3a41d9..034c98b0 100644 --- a/infrastructure/terraform/modules/ssl/README.md +++ b/infrastructure/terraform/modules/ssl/README.md @@ -6,14 +6,14 @@ ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.10.1 | | [tls](#requirement\_tls) | 4.1.0 | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes | | [component](#input\_component) | The name of the tfscaffold component | `string` | n/a | yes | | [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no | @@ -31,7 +31,7 @@ ## Outputs | Name | Description | -|------|-------------| +| ---- | ----------- | | [cacert\_pem](#output\_cacert\_pem) | Truststore | | [server\_crt](#output\_server\_crt) | Server Certificate | | [server\_key](#output\_server\_key) | Server Key | diff --git a/scripts/config/markdownlint.yaml b/scripts/config/markdownlint.yaml index 554ab554..fb2bca84 100644 --- a/scripts/config/markdownlint.yaml +++ b/scripts/config/markdownlint.yaml @@ -9,3 +9,6 @@ MD024: # https://github.com/DavidAnson/markdownlint/blob/main/doc/md033.md MD033: false + +# https://github.com/DavidAnson/markdownlint/blob/main/doc/md060.md +MD060: false diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index afc0f2a8..84305710 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -8,6 +8,7 @@ repos: - id: check-added-large-files - id: check-symlinks - id: detect-private-key + exclude: 'src/utils/src/__tests__/key-generation-utils/(get-private-key|validate-private-key|jwk-key)\.test\.ts$' - id: end-of-file-fixer - id: forbid-new-submodules - id: mixed-line-ending