diff --git a/.github/workflows/sync_oscal_cac.yml b/.github/workflows/sync_oscal_cac.yml new file mode 100644 index 000000000..0aed49323 --- /dev/null +++ b/.github/workflows/sync_oscal_cac.yml @@ -0,0 +1,163 @@ +name: Sync OSCAL content to CAC content +permissions: + contents: write + pull-requests: read +on: + #push: + # branches: + # - master + pull_request: + types: [opened, synchronize, reopened] + +jobs: + check-oscal-content-update-sync-to-cac: + runs-on: ubuntu-latest + steps: + # Step 1: Set up Python 3 + - name: Set up Python 3 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.9' + # Step 2: Install Git + - name: Install Git + run: sudo apt-get update && sudo apt-get install -y git + # Step 3: Checkout OSCAL repo + - name: Checkout OSCAL repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + repository: ${{ github.repository }} + path: oscal-content + - name: Get the commit message and PR number + run: | + # cd oscal-content + # # Get the latest commit message + # COMMIT_MSG=$(git log -1 --pretty=%B) + # # Extract the PR number from the commit message (if it's a merge commit) + # PR_NUMBER=$(echo "$COMMIT_MSG" | grep -oP '#\K\d+') + # if [ -n "$PR_NUMBER" ]; then + # echo "Found PR number: $PR_NUMBER" + # echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV + # echo "SKIP=false" >> $GITHUB_ENV + # PR_INFO=$(curl -s "https://api.github.com/repos/${{ github.repository }}/pulls/${PR_NUMBER}") + # # Extract PR title from the response + # PR_TITLE=$(echo "$PR_INFO" | jq -r .title) + # echo "PR Title: $PR_TITLE" + # if [[ "$PR_TITLE" == *"Auto-generated PR from CAC"* ]]; then + # echo "The PR comes from CAC content. The workflow of Sync OSCAL content to CAC will exit." + # echo "Skipping further checks." + # echo "SKIP=true" >> $GITHUB_ENV + # fi + # fi + echo "PR_NUMBER=33" >> $GITHUB_ENV + echo "SKIP=false" >> $GITHUB_ENV + # Step 4: Get the access token for content write permission to CAC content + - name: Get GitHub app token + if: ${{ env.SKIP == 'false' }} + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 + id: app-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + repositories: | + content + oscal-content + # Step 6: Dectect the updates of OSCAL content + - name: Detect the changed files of the PR + id: changed-files + run: | + repo=${{ github.repository }} + # Fetch all pages of the files for the pull request + url="repos/$repo/pulls/${{ env.PR_NUMBER }}/files" + response=$(gh api "$url" --paginate) + echo "$response" | jq -r '.[].filename' > filenames.txt + echo "CHANGE_FOUND=false" >> $GITHUB_ENV + if grep -E "catalogs/|profiles/|component-definitions/" filenames.txt ; then + echo "CHANGE_FOUND=true" >> $GITHUB_ENV + fi + cat filenames.txt + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + - name: Checkout CAC repo + if: ${{ env.CHANGE_FOUND == 'true' }} + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + repository: ComplianceAsCode/content + path: cac-content + token: ${{ steps.app-token.outputs.token }} + fetch-depth: 0 + - name: Checkout complyscribe repo + if: ${{ env.CHANGE_FOUND == 'true' }} + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + repository: complytime/complyscribe + path: complyscribe + - name: Setup trestlebot + if: ${{ env.CHANGE_FOUND == 'true' }} + run: | + cd complyscribe && python3 -m venv venv && source venv/bin/activate + python3 -m pip install --no-cache-dir "poetry==1.7.1" + poetry install + # Step 8: Sync OSCAL content to CAC content + - name: Sync OSCAL content to CAC content + if: ${{ env.CHANGE_FOUND == 'true' }} + run: | + pr_number="${{ github.event.pull_request.number }}" + cat filenames.txt + cd complyscribe && source venv/bin/activate + while IFS= read -r line; do + if [[ "$line" == *catalogs* ]]; then + echo "sync oscal catalogs according to update of $line ..." + policy_id=$(echo "$line" | cut -f2 -d"/") + echo "The policy_id is $policy_id" + poetry run complyscribe sync-oscal-content catalog --repo-path ../oscal-content --committer-email "openscap-ci@gmail.com" --committer-name "openscap-ci" --branch "sync_oscal_pr$pr_number" --cac-content-root "$GITHUB_WORKSPACE/cac-content" --cac-policy-id "$policy_id" + elif [[ "$line" == "profiles"* ]]; then + echo "sync oscal profiles according to update of $line ..." + policy_id=$(echo $line | cut -f2 -d"/" | cut -f2 -d"-") + product=$(echo "$line" | cut -f2 -d"/" | cut -f1 -d"-") + echo "The policy_id is $policy_id, the product is $product" + poetry run complyscribe sync-oscal-content profile --repo-path ../oscal-content --committer-email "openscap-ci@gmail.com" --committer-name "openscap-ci" --branch "sync_oscal_pr$pr_number" --cac-content-root "$GITHUB_WORKSPACE/cac-content" --cac-policy-id "$policy_id" --product "$product" + elif [[ "$line" == "component-definitions"* ]]; then + echo "sync oscal component-definitions according to update of $line ..." + product=$(echo "$line" | cut -f2 -d"/") + profile=$(echo "$line" | cut -f3 -d"/") + echo "The product is $product, the profile is $profile" + poetry run complyscribe sync-oscal-content component-definition --repo-path ../oscal-content --committer-email "openscap-ci@gmail.com" --committer-name "openscap-ci" --branch "sync_oscal_pr$pr_number" --cac-content-root "$GITHUB_WORKSPACE/cac-content" --product "$product" --oscal-profile "$profile" + fi + done < ../filenames.txt + # Step 9: Create PR to CAC content + - name: Create a Pull Request to OSCAL content + if: ${{ env.CHANGE_FOUND == 'true' }} + run: | + cd cac-content + BRANCH_NAME="sync_oscal_pr${{ env.PR_NUMBER }}" + OWNER="ComplianceAsCode" + REPO="content" + if [[ "$(git branch --show-current)" == "$BRANCH_NAME" ]]; then + # Check if the PR exists + PR_EXISTS=$(gh pr list --repo $OWNER/$REPO \ + --head $BRANCH_NAME --state open --json id \ + | jq length) + # Get commits between main and branch + commits=$(git log master..$BRANCH_NAME --oneline) + # If the PR does not exist and there are commits in the branch, + # then create a PR for this branch. + if [ "$PR_EXISTS" -gt 0 ]; then + echo "PR $BRANCH_NAME already exists. Skipping PR creation." + elif [ -z "$commits" ]; then + echo "No commits between main and $BRANCH_NAME. Skipping PR creation." + else + echo "Creating PR for new branch: $BRANCH_NAME" + gh pr create --repo $OWNER/$REPO \ + --title "Auto-generated PR from OSCAL ${{ env.PR_NUMBER }}" \ + --head "$BRANCH_NAME" \ + --base "master" \ + --body "[WIP]This is an auto-generated PR from OSCAL ${{ env.PR_NUMBER }} updates" + fi + else + echo "No branch $BRANCH_NAME. Skipping PR creation." + fi + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + + diff --git a/catalogs/cis_rhel10/catalog.json b/catalogs/cis_rhel10/catalog.json index ddfa65986..529cf707b 100644 --- a/catalogs/cis_rhel10/catalog.json +++ b/catalogs/cis_rhel10/catalog.json @@ -2119,21 +2119,6 @@ "id": "cis_rhel10_4-1", "title": "REPLACE_ME", "controls": [ - { - "id": "cis_rhel10_4-1.1", - "class": "CAC_IMPORT", - "title": "Ensure Nftables Is Installed (Automated)", - "props": [ - { - "name": "label", - "value": "4.1.1" - }, - { - "name": "sort-id", - "value": "cis_rhel10_4-01.01" - } - ] - }, { "id": "cis_rhel10_4-1.2", "class": "CAC_IMPORT", diff --git a/catalogs/cis_rhel9/catalog.json b/catalogs/cis_rhel9/catalog.json index 612252a44..a085cc177 100644 --- a/catalogs/cis_rhel9/catalog.json +++ b/catalogs/cis_rhel9/catalog.json @@ -29,27 +29,6 @@ } ] }, - { - "id": "enable_authselect", - "title": "REPLACE_ME", - "controls": [ - { - "id": "enable_authselect", - "class": "CAC_IMPORT", - "title": "Enable Authselect", - "props": [ - { - "name": "label", - "value": "enable_authselect" - }, - { - "name": "sort-id", - "value": "enable_authselect" - } - ] - } - ] - }, { "id": "cis_rhel9_1", "title": "REPLACE_ME", diff --git a/component-definitions/rhel10/rhel10-anssi-high/component-definition.json b/component-definitions/rhel10/rhel10-anssi-high/component-definition.json index 77e5df580..b14fd8b5b 100644 --- a/component-definitions/rhel10/rhel10-anssi-high/component-definition.json +++ b/component-definitions/rhel10/rhel10-anssi-high/component-definition.json @@ -14,18 +14,6 @@ "title": "rhel10", "description": "Red Hat Enterprise Linux 10", "props": [ - { - "name": "Rule_Id", - "ns": "https://oscal-compass.github.io/compliance-trestle/schemas/oscal/cd", - "value": "kernel_config_strict_kernel_rwx", - "remarks": "rule_set_00" - }, - { - "name": "Rule_Description", - "ns": "https://oscal-compass.github.io/compliance-trestle/schemas/oscal/cd", - "value": "Make the kernel text and rodata read-only", - "remarks": "rule_set_00" - }, { "name": "Parameter_Id_0", "ns": "https://oscal-compass.github.io/compliance-trestle/schemas/oscal/cd", diff --git a/profiles/rhel8-anssi-high/profile.json b/profiles/rhel8-anssi-high/profile.json index 8938cb31c..7d84117c8 100644 --- a/profiles/rhel8-anssi-high/profile.json +++ b/profiles/rhel8-anssi-high/profile.json @@ -13,7 +13,6 @@ "include-controls": [ { "with-ids": [ - "r1", "r10", "r11", "r12", diff --git a/profiles/rhel9-anssi-enhanced/profile.json b/profiles/rhel9-anssi-enhanced/profile.json index c6746c649..dcf260571 100644 --- a/profiles/rhel9-anssi-enhanced/profile.json +++ b/profiles/rhel9-anssi-enhanced/profile.json @@ -13,7 +13,6 @@ "include-controls": [ { "with-ids": [ - "r1", "r10", "r11", "r12",