tc-scanner
v0.3.0
Published
CI security scanner and controls runner. Scan Dockerfiles, images, dependencies, and secrets. Run all security controls with one command.
Maintainers
Readme
tc-scanner
A CI security scanner for Dockerfiles, container images, dependencies, and secrets. Powered by Trivy.
Requirements
Docker is required. The scanner runs Trivy inside a container, so no additional installation is needed. All major CI platforms (Bitbucket Pipelines, GitHub Actions, GitLab CI) have Docker available by default.
Installation
No installation required. Use directly with npx:
npx tc-scanner scan ./DockerfileOr install globally:
npm install -g tc-scanner
tc-scan scan ./DockerfileQuick Start
# Scan a Dockerfile for misconfigurations
npx tc-scanner scan ./Dockerfile
# Scan project dependencies for known vulnerabilities
npx tc-scanner deps .
# Scan code for hardcoded secrets
npx tc-scanner secrets ./src
# Scan a container image
npx tc-scanner image nginx:latestCommands
scan - Dockerfile Security
Scans Dockerfiles for security misconfigurations.
npx tc-scanner scan ./Dockerfile
npx tc-scanner scan ./Dockerfile --severity HIGH
npx tc-scanner scan ./Dockerfile --output ./reports/dockerfile-scanWhat it detects:
- Running as root user
- Missing HEALTHCHECK instruction
- Using
latesttag instead of pinned versions - Insecure
ADDinstead ofCOPY - Exposed sensitive ports
- Missing USER instruction
deps - Dependency Vulnerabilities
Scans package lockfiles for known CVEs (similar to Snyk/npm audit).
npx tc-scanner deps .
npx tc-scanner deps ./backend --severity CRITICAL
npx tc-scanner deps . --include-devSupported lockfiles:
package-lock.json(npm)yarn.lock(Yarn)pnpm-lock.yaml(pnpm)Gemfile.lock(Ruby)requirements.txt/Pipfile.lock(Python)go.sum(Go)composer.lock(PHP)
secrets - Secret Detection
Scans code for hardcoded secrets and sensitive data.
npx tc-scanner secrets .
npx tc-scanner secrets ./src --output ./reports/secretsWhat it detects:
- AWS access keys and secrets
- API tokens (Stripe, GitHub, Slack, etc.)
- Private keys (RSA, SSH, PGP)
- Database connection strings
- Hardcoded passwords
- JWT secrets
image - Container Image Scanning
Scans container images for OS and application vulnerabilities.
npx tc-scanner image nginx:latest
npx tc-scanner image myapp:v1.2.3 --severity HIGH,CRITICALWhat it detects:
- OS package vulnerabilities (Alpine, Debian, Ubuntu, RHEL, etc.)
- Application dependencies inside the image
- Embedded secrets and misconfigurations
Options
| Option | Alias | Description | Default |
|--------|-------|-------------|---------|
| --severity | -s | Minimum severity level: LOW, MEDIUM, HIGH, CRITICAL | HIGH |
| --output | -o | Save reports to file (creates .json, .txt, .html) | - |
| --webhook | -w | Send results to a webhook URL | - |
| --exit-code | - | Exit code when issues are found | 1 |
| --include-dev | - | Include dev dependencies (deps command only) | false |
Reports
Generate reports in multiple formats:
npx tc-scanner scan ./Dockerfile --output ./reports/scan-reportThis creates:
scan-report.json- Structured data for APIs and integrationsscan-report.txt- Plain text for email notificationsscan-report.html- Styled HTML report for attachments
Webhooks
Send scan results to any webhook endpoint:
# Generic webhook
npx tc-scanner scan ./Dockerfile --webhook https://your-api.com/security-alerts
# Slack incoming webhook
npx tc-scanner scan ./Dockerfile --webhook https://hooks.slack.com/services/xxx/yyy/zzzWebhook payload:
{
"scanner": "tc-scanner",
"scanType": "dockerfile",
"timestamp": "2024-01-15T10:30:00.000Z",
"target": "./Dockerfile",
"summary": {
"total": 3,
"critical": 0,
"high": 1,
"medium": 2,
"low": 0
},
"issues": [
{
"id": "DS-0002",
"severity": "HIGH",
"title": "Last USER command should not be 'root'",
"description": "Running containers with 'root' user can lead to container escape.",
"url": "https://avd.aquasec.com/misconfig/ds-0002"
}
]
}CI/CD Integration
Bitbucket Pipelines
image: node:20
definitions:
services:
docker:
memory: 2048
pipelines:
default:
- step:
name: Security Scan
services:
- docker
script:
- npx tc-scanner scan ./Dockerfile --severity HIGH
- npx tc-scanner deps . --severity HIGH
# Send results to Slack or custom webhook
- npx tc-scanner scan ./Dockerfile --webhook $SECURITY_WEBHOOK_URL --exit-code 0
pull-requests:
'**':
- step:
name: PR Security Check
services:
- docker
script:
- npx tc-scanner scan ./Dockerfile --severity CRITICAL
- npx tc-scanner secrets ./srcNote: Add
SECURITY_WEBHOOK_URLas a repository variable in Bitbucket settings for webhook notifications.
GitHub Actions
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan Dockerfile
run: npx tc-scanner scan ./Dockerfile --severity HIGH
- name: Scan Dependencies
run: npx tc-scanner deps . --severity HIGH
- name: Scan for Secrets
run: npx tc-scanner secrets ./srcGitLab CI
security-scan:
image: node:20
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
script:
- npx tc-scanner scan ./Dockerfile --severity HIGH
- npx tc-scanner deps . --severity HIGH
- npx tc-scanner secrets ./src
artifacts:
paths:
- reports/
when: alwaysControls Platform Integration (tc-admin)
For normalized control ingestion into tc-admin, use:
- emitter script:
./scripts/emit-check-run.mjs - pipeline template:
./examples/bitbucket-pipelines.controls.example.yml
Required CI variables:
TC_ADMIN_BASE_URL(example:https://tc-admin.internal)SERVICE_API_KEY(shared ingest key)CLIENT_NAME(tenant/client label)
Quality-gate readiness check:
# Human-readable readiness output
npx tc-scanner quality-gate . --ci-provider bitbucket
# JSON output for automation
npx tc-scanner quality-gate . --ci-provider bitbucket --json
# Fail CI when gate is not enabled
npx tc-scanner quality-gate . --ci-provider bitbucket --strictThe check inspects:
- Presence of
bitbucket-pipelines.yml - Control pipeline signals (e.g.
tc-scan controls, emit script, scan/test commands) - Required ingestion env vars (
TC_ADMIN_BASE_URL,SERVICE_API_KEY,CLIENT_NAME)
The template posts these control codes:
SEC_DEP_PATCHSEC_CONTAINER_VULNSEC_SECRETSCODE_STATICQA_TESTS
Exit Codes
| Code | Meaning |
|------|---------|
| 0 | No issues found (or below severity threshold) |
| 1 | Issues found at or above severity threshold |
Use --exit-code 0 to always pass (useful for non-blocking scans):
npx tc-scanner scan ./Dockerfile --exit-code 0Severity Levels
| Level | Description |
|-------|-------------|
| CRITICAL | Severe vulnerabilities requiring immediate action |
| HIGH | Important security issues that should be fixed soon |
| MEDIUM | Moderate issues to address in regular maintenance |
| LOW | Minor issues or best practice recommendations |
Examples
Fail CI only on critical issues:
npx tc-scanner scan ./Dockerfile --severity CRITICALFull security audit with reports:
npx tc-scanner scan ./Dockerfile --output ./reports/dockerfile --severity LOW
npx tc-scanner deps . --output ./reports/deps --severity LOW --include-dev
npx tc-scanner secrets ./src --output ./reports/secretsSend alerts to Slack on failures:
npx tc-scanner scan ./Dockerfile --webhook $SLACK_WEBHOOK_URLTroubleshooting
"Docker is required"
- Ensure Docker is installed and running
- In CI, enable the Docker service (see examples above)
"No lockfile found" (deps command)
- The scanner needs
package-lock.json,yarn.lock, or similar - Run
npm installor your package manager to generate a lockfile
Slow first run
- First run downloads the Trivy Docker image (~50MB) and vulnerability database (~80MB)
- Subsequent runs are faster due to caching
