Skip to content

Commit

Permalink
Improve certificate handling and GitHub Actions security
Browse files Browse the repository at this point in the history
- Add scripts for certificate splitting and GitHub secret management
- Update workflow files with proper security permissions
- Implement flexible certificate assembly from multiple parts
- Update documentation for certificate management
- Enhance .gitignore for certificate-related files
  • Loading branch information
aaronlippold committed Feb 26, 2025
1 parent dc2bc7b commit 876e593
Show file tree
Hide file tree
Showing 11 changed files with 999 additions and 110 deletions.
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ComplianceAsCode Builder Environment Configuration
# Copy this file to .env and modify as needed

# Build Configuration
BUILD_TYPE=full # Options: full, minimal
PRODUCT=rhel10 # Default product to build

# Certificate Configuration
# If you need to specify a custom certificate location
# CERT_PATH=/path/to/your/ca-bundle.pem
# EXTRA_CERT_PATH=/path/to/extra-cert.pem

# Docker Configuration
# DOCKER_BUILDKIT=1 # Enable Docker BuildKit for faster builds
# COMPOSE_PROJECT_NAME=cac-builder

# GitHub Configuration (for workflows)
# GITHUB_TOKEN= # For GitHub API access (don't commit actual tokens!)

# Network Configuration
# HTTP_PROXY=http://proxy.example.com:8080
# HTTPS_PROXY=http://proxy.example.com:8080
# NO_PROXY=localhost,127.0.0.1

# Resource Limits
# DOCKER_MEMORY=8g # Container memory limit
# DOCKER_CPUS=4 # Container CPU limit
16 changes: 16 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ This workflow publishes container images to GitHub Container Registry when chang
- Tags images appropriately based on version/branch
- Makes containers available for users without building locally

## Security Considerations

All workflows in this repository follow GitHub's security best practices:

1. **Least Privilege Principle**: Workflows are granted only the permissions they need to function:
- Build & Test workflows: `contents: read`, `packages: read`
- Publish workflows: `contents: read`, `packages: write`

2. **Secret Management**: Sensitive data like certificates are handled using GitHub Secrets.

3. **Pinned Action Versions**: All external actions use specific versions instead of floating tags.

4. **Workflow Token Permissions**: GitHub's `GITHUB_TOKEN` is granted only required permissions.

For more information about GitHub Actions security, see the [GitHub Actions documentation](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions).

## Usage

### Using the published containers
Expand Down
42 changes: 39 additions & 3 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ on:
pull_request:
branches: [ main ]

# Set permissions explicitly for security best practices
permissions:
contents: read # For checking out code
packages: read # For pulling container images
# Note: For PR builds, we don't need write permissions

jobs:
build:
name: Build and Test Containers
Expand All @@ -18,12 +24,42 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Create empty certificate file for build
- name: Create certificate file for build
run: |
mkdir -p certs/org
touch certs/org/mitre-ca-bundle.pem
# Modified to ensure Dockerfiles exist instead of relying on symlinks
# Function to create certificate from parts
create_cert_from_parts() {
# Start with an empty file
: > certs/org/ca-bundle.pem
# Add each available part (up to 20 parts)
for i in {1..20}; do
SECRET_NAME="CA_BUNDLE_PART$i"
if [ -n "$(eval echo \${{ secrets.$SECRET_NAME }})" ]; then
echo "Adding certificate part $i"
echo "$(eval echo \${{ secrets.$SECRET_NAME }})" >> certs/org/ca-bundle.pem
else
# Stop when we run out of parts
break
fi
done
echo "Using CA certificate assembled from multiple parts"
}
# First try using single secret
if [ -n "${{ secrets.CA_BUNDLE }}" ]; then
echo "${{ secrets.CA_BUNDLE }}" > certs/org/ca-bundle.pem
echo "Using CA certificate from single secret"
# Next try using split certificate parts
elif [ -n "${{ secrets.CA_BUNDLE_PART1 }}" ]; then
create_cert_from_parts
else
# Fallback to empty file
touch certs/org/empty-ca-bundle.pem
echo "Using empty CA certificate file"
- name: Prepare Dockerfiles
run: |
# Instead of relying on symlinks, directly reference the actual files
Expand Down
52 changes: 47 additions & 5 deletions .github/workflows/publish-container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ on:
tags: [ 'v*' ]
workflow_dispatch:

# Set explicit permissions - only grant what's needed
permissions:
contents: read # Needed to check out the repository
packages: write # Needed to push to GitHub Container Registry
# The following permissions are NOT needed and should remain at default (none):
# - issues
# - pull-requests
# - actions
# - security-events
# - id-token
# - deployments

jobs:
push-to-registry:
name: Push containers to GitHub Container Registry
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
# Job-level permissions are already set at workflow level

steps:
- name: Checkout repository
Expand All @@ -21,10 +31,42 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Create empty certificate file for build
- name: Create certificate file for build
run: |
mkdir -p certs/org
touch certs/org/mitre-ca-bundle.pem
# Function to create certificate from parts
create_cert_from_parts() {
# Start with an empty file
: > certs/org/ca-bundle.pem
# Add each available part (up to 20 parts)
for i in {1..20}; do
SECRET_NAME="CA_BUNDLE_PART$i"
if [ -n "$(eval echo \${{ secrets.$SECRET_NAME }})" ]; then
echo "Adding certificate part $i"
echo "$(eval echo \${{ secrets.$SECRET_NAME }})" >> certs/org/ca-bundle.pem
else
# Stop when we run out of parts
break
fi
done
echo "Using CA certificate assembled from multiple parts"
}
# First try using single secret
if [ -n "${{ secrets.CA_BUNDLE }}" ]; then
echo "${{ secrets.CA_BUNDLE }}" > certs/org/ca-bundle.pem
echo "Using CA certificate from single secret"
# Next try using split certificate parts
elif [ -n "${{ secrets.CA_BUNDLE_PART1 }}" ]; then
create_cert_from_parts
else
# Fallback to empty file
touch certs/org/empty-ca-bundle.pem
echo "Using empty CA certificate file"
fi
# Modified to ensure Dockerfiles exist instead of relying on symlinks
- name: Prepare Dockerfiles
Expand Down
99 changes: 63 additions & 36 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,45 +1,72 @@
# Certificates
certs/org/*.pem
!certs/org/.gitkeep
# Ignore certificate files
certs/
*.pem
*.crt
*.key
*.p12
*.pfx
*.jks

# Build artifacts
output/*
!output/.gitkeep
# Ignore split certificate directory and files
split-certs/
**/split-certs/
part*.pem
chunk-*

# Environment files
# Environment and secrets
.env
.env.local
.env.*.local
.secrets

# Docker related
.docker/

# Temporary files
*.tmp
*.bak
*.swp
*~

# macOS specific files
.DS_Store
.AppleDouble
.LSOverride
# Build artifacts
build/
output/
dist/
*.o
*.a
*.so
*.dylib
*.dll

# Windows specific files
Thumbs.db
ehthumbs.db
Desktop.ini
# Container-related
.container-*
.docker-*

# IDE files
.idea/
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history
*.code-workspace

# Python
# Python-related
__pycache__/
*.py[cod]
*$py.class
.pytest_cache/
*.so
.Python
env/
venv/
ENV/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Node.js related
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# IDE specific files
.idea/
.vscode/
*.swp
*.swo
.DS_Store
70 changes: 56 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ For more details on build types, see [docs/BUILD-TYPES.md](docs/BUILD-TYPES.md).

You can configure certificates for secure connections:

1. **Default CA Certificate**
- Uses MITRE CA bundle at `~/.aws/mitre-ca-bundle.pem`
- Automatically copied to `./certs/org/mitre-ca-bundle.pem`
1. **Default Certificate**
- Automatically looked for in the project setup
- Place certificate at `./certs/org/mitre-ca-bundle.pem`

2. **Custom CA Certificate**
- Specify with `--cert` option
Expand All @@ -80,6 +80,37 @@ You can configure certificates for secure connections:

For more details on certificate options, see [docs/CERTIFICATES.md](docs/CERTIFICATES.md).

## SCAP Content Types

The ComplianceAsCode builder can generate various types of SCAP content:

1. **XCCDF** (Extensible Configuration Checklist Description Format)
- Primary compliance standard format
- Contains benchmarks, rules, and profiles
- Example: `ssg-rhel10-xccdf.xml`

2. **OVAL** (Open Vulnerability and Assessment Language)
- Technical checking mechanisms
- Used by XCCDF for automated testing
- Example: `ssg-rhel10-oval.xml`

3. **DataStreams**
- Collection format that bundles XCCDF, OVAL, and other content
- Provides a single file for distribution
- Example: `ssg-rhel10-ds.xml`

4. **Ansible Playbooks**
- Remediation scripts in Ansible format
- Automatically fix non-compliant settings
- Located in `build/ansible`

5. **Bash Scripts**
- Remediation scripts in Bash format
- Fix non-compliant settings on Linux systems
- Located in `build/bash`

For a complete list of generated content types, check the `output/` directory after building a product.

## Setup and Usage

Run the setup script to prepare the environment:
Expand All @@ -92,6 +123,8 @@ Run the setup script to prepare the environment:
./setup.sh --build-type minimal --cert /path/to/ca-bundle.pem
```

You can also create a `.env` file for persistent configuration (see `.env.example` for available options).

For help with all available options:

```bash
Expand Down Expand Up @@ -122,17 +155,6 @@ build-product rhel10 # or any other product

Find the generated files in the `./output/` directory on your host machine.

## Integration with certsuite

The generated XCCDF files can be integrated with certsuite for compliance scanning:

```bash
# Example integration
certsuite compliance scan \
--xccdf ./output/ssg-rhel10-xccdf.xml \
--profile xccdf_org.ssgproject.content_profile_cis
```

## Workflow Options

This project supports different workflows depending on your needs:
Expand Down Expand Up @@ -162,6 +184,26 @@ docker-compose build --no-cache
docker-compose up -d
```

## For MITRE Team Members

When using this project within the MITRE network:

1. **Using Pre-built Containers**:
- The containers published to GitHub Container Registry are alreaady configured for MITRE.
- You can pull and use them directly:

```bash
docker pull ghcr.io/mitre/cac-builder:full
```

2. **Building Locally**:
- Clone the repository
- Place your company CA bundle at `./certs/org/your-ca-bundle.pem` if you are behind a corporate proxy or firewall.
- Run `./setup.sh`
- Build with `docker-compose build`

For details on certificate management, see [docs/CERTIFICATES.md](docs/CERTIFICATES.md).

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details and review our [Code of Conduct](CODE_OF_CONDUCT.md) before participating.
Expand Down
Loading

0 comments on commit 876e593

Please sign in to comment.