docs: align write-up report naming with the findings schema #494
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: container-ci | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - .dockerignore | |
| - .github/workflows/container-ci.yml | |
| - Dockerfile | |
| - Dockerfile.dockerignore | |
| - compose.yaml | |
| - compose.apparmor.yaml | |
| - docker/** | |
| - sdk/typescript/** | |
| pull_request: | |
| paths: | |
| - .dockerignore | |
| - .github/workflows/container-ci.yml | |
| - Dockerfile | |
| - Dockerfile.dockerignore | |
| - compose.yaml | |
| - compose.apparmor.yaml | |
| - docker/** | |
| - sdk/typescript/** | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| container: | |
| name: linux-amd64 | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Verify customer build excludes secrets and scan data | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ignore_file=.dockerignore | |
| if [[ -f Dockerfile.dockerignore ]]; then | |
| ignore_file=Dockerfile.dockerignore | |
| if ! cmp -s .dockerignore "$ignore_file"; then | |
| echo "Dockerfile-specific ignore rules must match the approved customer baseline." >&2 | |
| exit 1 | |
| fi | |
| fi | |
| if grep -Fq '!' "$ignore_file"; then | |
| echo "Customer Docker ignore rules must not re-include excluded files: $ignore_file" >&2 | |
| exit 1 | |
| fi | |
| for pattern in \ | |
| '**/.env' \ | |
| '**/.env.*' \ | |
| '**/.npmrc' \ | |
| '**/node_modules' \ | |
| '**/*.csv' \ | |
| '**/repositories.csv' \ | |
| '**/results' \ | |
| '**/security-scans' \ | |
| '**/state'; do | |
| if ! grep -Fxq -- "$pattern" "$ignore_file"; then | |
| echo "Missing customer Docker build exclusion in $ignore_file: $pattern" >&2 | |
| exit 1 | |
| fi | |
| done | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 | |
| - name: Build customer container | |
| uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 | |
| env: | |
| DOCKER_BUILD_RECORD_UPLOAD: "false" | |
| with: | |
| context: . | |
| load: true | |
| platforms: linux/amd64 | |
| push: false | |
| tags: codex-security:ci | |
| cache-from: type=gha,scope=codex-security-amd64 | |
| cache-to: ${{ github.event_name != 'pull_request' && 'type=gha,mode=max,scope=codex-security-amd64' || '' }} | |
| - name: Verify bundled scanner | |
| run: | | |
| docker run --rm codex-security:ci --version | |
| docker run --rm codex-security:ci bulk-scan --help | |
| docker run --rm codex-security:ci info --json | |
| - name: Validate hardened customer Compose configuration | |
| env: | |
| CODEX_SECURITY_IMAGE: codex-security:ci | |
| run: | | |
| mkdir -p results state | |
| chmod 700 results state | |
| printf 'id,repository,revision\n' > repositories.csv | |
| CODEX_SECURITY_USER="$(id -u):$(id -g)" | |
| export CODEX_SECURITY_USER | |
| docker compose config --quiet | |
| docker compose run --rm codex-security --version | |
| - name: Validate optional AppArmor Compose configuration | |
| env: | |
| CODEX_SECURITY_IMAGE: codex-security:ci | |
| run: docker compose -f compose.yaml -f compose.apparmor.yaml config --quiet | |
| - name: Verify hardened Codex command sandbox | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| command=( | |
| docker run --rm | |
| --cap-drop ALL | |
| --security-opt no-new-privileges | |
| --security-opt "seccomp=$GITHUB_WORKSPACE/docker/codex-security-seccomp.json" | |
| --entrypoint node | |
| codex-security:ci | |
| /usr/local/lib/node_modules/@openai/codex-security/node_modules/@openai/codex/bin/codex.js | |
| ) | |
| if output="$("${command[@]}" sandbox /usr/bin/true 2>&1)"; then | |
| printf '%s\n' "$output" | |
| elif grep -Eq 'bwrap: (Failed to make / slave: Permission denied|loopback: Failed RTM_NEW(ADDR|LINK): Operation not permitted|setting up uid map: Permission denied|No permissions to create a new namespace)' <<< "$output"; then | |
| echo '::notice::This Docker host blocks nested Bubblewrap namespaces; verifying the supported Landlock fallback.' | |
| "${command[@]}" sandbox --enable use_legacy_landlock /usr/bin/true | |
| else | |
| printf 'The hardened Codex sandbox failed unexpectedly:\n%s\n' "$output" >&2 | |
| exit 1 | |
| fi | |
| - name: Reject interactive repository discovery | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if output="$(docker run --rm -t codex-security:ci bulk-scan 2>&1)"; then | |
| echo "The customer container must require a repository CSV." >&2 | |
| exit 1 | |
| else | |
| status=$? | |
| fi | |
| if [[ "$status" -ne 2 ]]; then | |
| printf 'The customer container returned unexpected exit status %s:\n%s\n' "$status" "$output" >&2 | |
| exit 1 | |
| fi | |
| expected='codex-security: bulk-scan requires a repository CSV; interactive discovery is not supported in this image.' | |
| if [[ "${output//$'\r'/}" != "$expected" ]]; then | |
| printf 'The customer container returned an unexpected repository discovery error:\n%s\n' "$output" >&2 | |
| exit 1 | |
| fi | |
| - name: Verify host-scoped noninteractive Git credentials | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| docker run --rm \ | |
| --entrypoint /bin/sh \ | |
| --env GH_TOKEN=SYNTHETIC_GITHUB_TOKEN \ | |
| codex-security:ci \ | |
| -ec 'actual="$(printf "protocol=https\nhost=github.com\n\n" | /usr/local/bin/codex-security-git-credential get)"; test "$actual" = "$(printf "username=x-access-token\npassword=SYNTHETIC_GITHUB_TOKEN")"; test -z "$(printf "protocol=https\nhost=untrusted.example\n\n" | /usr/local/bin/codex-security-git-credential get)"' |