tc-scanner 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,46 +1,177 @@
1
1
  # tc-scanner
2
2
 
3
- CI security scanner for Dockerfiles, dependencies, and secrets. Powered by Trivy.
3
+ A CI security scanner for Dockerfiles, container images, dependencies, and secrets. Powered by [Trivy](https://trivy.dev/).
4
4
 
5
5
  ## Requirements
6
6
 
7
- **Docker is required.** Trivy runs inside a container - no other installation needed. All major CI platforms (Bitbucket, GitHub Actions, GitLab CI, CircleCI) have Docker available.
7
+ **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, CircleCI) have Docker available by default.
8
8
 
9
- ## One-Line Usage
9
+ ## Installation
10
+
11
+ No installation required. Use directly with `npx`:
12
+
13
+ ```bash
14
+ npx tc-scanner scan ./Dockerfile
15
+ ```
16
+
17
+ Or install globally:
18
+
19
+ ```bash
20
+ npm install -g tc-scanner
21
+ tc-scan scan ./Dockerfile
22
+ ```
23
+
24
+ ## Quick Start
10
25
 
11
26
  ```bash
12
- # Scan a Dockerfile
27
+ # Scan a Dockerfile for misconfigurations
13
28
  npx tc-scanner scan ./Dockerfile
14
29
 
15
- # Scan dependencies (requires package-lock.json, yarn.lock, or pnpm-lock.yaml)
16
- npx tc-scanner deps ./my-project
30
+ # Scan project dependencies for known vulnerabilities
31
+ npx tc-scanner deps .
17
32
 
18
- # Scan for secrets
33
+ # Scan code for hardcoded secrets
19
34
  npx tc-scanner secrets ./src
20
35
 
21
36
  # Scan a container image
22
37
  npx tc-scanner image nginx:latest
23
38
  ```
24
39
 
25
- ## Send Results to Webhook
40
+ ## Commands
41
+
42
+ ### `scan` - Dockerfile Security
43
+
44
+ Scans Dockerfiles for security misconfigurations.
45
+
46
+ ```bash
47
+ npx tc-scanner scan ./Dockerfile
48
+ npx tc-scanner scan ./Dockerfile --severity HIGH
49
+ npx tc-scanner scan ./Dockerfile --output ./reports/dockerfile-scan
50
+ ```
51
+
52
+ **What it detects:**
53
+ - Running as root user
54
+ - Missing HEALTHCHECK instruction
55
+ - Using `latest` tag instead of pinned versions
56
+ - Insecure `ADD` instead of `COPY`
57
+ - Exposed sensitive ports
58
+ - Missing USER instruction
59
+
60
+ ### `deps` - Dependency Vulnerabilities
61
+
62
+ Scans package lockfiles for known CVEs (similar to Snyk/npm audit).
63
+
64
+ ```bash
65
+ npx tc-scanner deps .
66
+ npx tc-scanner deps ./backend --severity CRITICAL
67
+ npx tc-scanner deps . --include-dev
68
+ ```
69
+
70
+ **Supported lockfiles:**
71
+ - `package-lock.json` (npm)
72
+ - `yarn.lock` (Yarn)
73
+ - `pnpm-lock.yaml` (pnpm)
74
+ - `Gemfile.lock` (Ruby)
75
+ - `requirements.txt` / `Pipfile.lock` (Python)
76
+ - `go.sum` (Go)
77
+ - `composer.lock` (PHP)
78
+
79
+ ### `secrets` - Secret Detection
80
+
81
+ Scans code for hardcoded secrets and sensitive data.
82
+
83
+ ```bash
84
+ npx tc-scanner secrets .
85
+ npx tc-scanner secrets ./src --output ./reports/secrets
86
+ ```
87
+
88
+ **What it detects:**
89
+ - AWS access keys and secrets
90
+ - API tokens (Stripe, GitHub, Slack, etc.)
91
+ - Private keys (RSA, SSH, PGP)
92
+ - Database connection strings
93
+ - Hardcoded passwords
94
+ - JWT secrets
95
+
96
+ ### `image` - Container Image Scanning
97
+
98
+ Scans container images for OS and application vulnerabilities.
99
+
100
+ ```bash
101
+ npx tc-scanner image nginx:latest
102
+ npx tc-scanner image myapp:v1.2.3 --severity HIGH,CRITICAL
103
+ ```
104
+
105
+ **What it detects:**
106
+ - OS package vulnerabilities (Alpine, Debian, Ubuntu, RHEL, etc.)
107
+ - Application dependencies inside the image
108
+ - Embedded secrets and misconfigurations
109
+
110
+ ## Options
111
+
112
+ | Option | Alias | Description | Default |
113
+ |--------|-------|-------------|---------|
114
+ | `--severity` | `-s` | Minimum severity level: `LOW`, `MEDIUM`, `HIGH`, `CRITICAL` | `HIGH` |
115
+ | `--output` | `-o` | Save reports to file (creates `.json`, `.txt`, `.html`) | - |
116
+ | `--webhook` | `-w` | Send results to a webhook URL | - |
117
+ | `--exit-code` | - | Exit code when issues are found | `1` |
118
+ | `--include-dev` | - | Include dev dependencies (deps command only) | `false` |
119
+
120
+ ## Reports
121
+
122
+ Generate reports in multiple formats:
123
+
124
+ ```bash
125
+ npx tc-scanner scan ./Dockerfile --output ./reports/scan-report
126
+ ```
127
+
128
+ This creates:
129
+ - `scan-report.json` - Structured data for APIs and integrations
130
+ - `scan-report.txt` - Plain text for email notifications
131
+ - `scan-report.html` - Styled HTML report for attachments
132
+
133
+ ## Webhooks
134
+
135
+ Send scan results to any webhook endpoint:
26
136
 
27
137
  ```bash
28
- npx tc-scanner scan ./Dockerfile --webhook https://your-webhook.com/endpoint
29
- npx tc-scanner deps . --webhook https://hooks.slack.com/services/xxx
138
+ # Generic webhook
139
+ npx tc-scanner scan ./Dockerfile --webhook https://your-api.com/security-alerts
140
+
141
+ # Slack incoming webhook
142
+ npx tc-scanner scan ./Dockerfile --webhook https://hooks.slack.com/services/xxx/yyy/zzz
30
143
  ```
31
144
 
32
- Webhook payload:
145
+ **Webhook payload:**
146
+
33
147
  ```json
34
148
  {
35
149
  "scanner": "tc-scanner",
36
150
  "scanType": "dockerfile",
37
151
  "timestamp": "2024-01-15T10:30:00.000Z",
38
- "summary": { "total": 2, "critical": 0, "high": 1, "medium": 1, "low": 0 },
39
- "issues": [...]
152
+ "target": "./Dockerfile",
153
+ "summary": {
154
+ "total": 3,
155
+ "critical": 0,
156
+ "high": 1,
157
+ "medium": 2,
158
+ "low": 0
159
+ },
160
+ "issues": [
161
+ {
162
+ "id": "DS-0002",
163
+ "severity": "HIGH",
164
+ "title": "Last USER command should not be 'root'",
165
+ "description": "Running containers with 'root' user can lead to container escape.",
166
+ "url": "https://avd.aquasec.com/misconfig/ds-0002"
167
+ }
168
+ ]
40
169
  }
41
170
  ```
42
171
 
43
- ## Bitbucket Pipelines
172
+ ## CI/CD Integration
173
+
174
+ ### Bitbucket Pipelines
44
175
 
45
176
  ```yaml
46
177
  image: node:20
@@ -59,72 +190,138 @@ pipelines:
59
190
  script:
60
191
  - npx tc-scanner scan ./Dockerfile --severity HIGH
61
192
  - npx tc-scanner deps . --severity HIGH
193
+
194
+ pull-requests:
195
+ '**':
196
+ - step:
197
+ name: PR Security Check
198
+ services:
199
+ - docker
200
+ script:
201
+ - npx tc-scanner scan ./Dockerfile --severity CRITICAL
202
+ - npx tc-scanner secrets ./src
62
203
  ```
63
204
 
64
- ## GitHub Actions
205
+ ### GitHub Actions
65
206
 
66
207
  ```yaml
208
+ name: Security Scan
209
+
210
+ on: [push, pull_request]
211
+
67
212
  jobs:
68
213
  security:
69
214
  runs-on: ubuntu-latest
70
215
  steps:
71
216
  - uses: actions/checkout@v4
72
- - name: Security Scan
73
- run: |
74
- npx tc-scanner scan ./Dockerfile --severity HIGH
75
- npx tc-scanner deps . --severity HIGH
217
+
218
+ - name: Scan Dockerfile
219
+ run: npx tc-scanner scan ./Dockerfile --severity HIGH
220
+
221
+ - name: Scan Dependencies
222
+ run: npx tc-scanner deps . --severity HIGH
223
+
224
+ - name: Scan for Secrets
225
+ run: npx tc-scanner secrets ./src
76
226
  ```
77
227
 
78
- ## GitLab CI
228
+ ### GitLab CI
79
229
 
80
230
  ```yaml
81
231
  security-scan:
82
232
  image: node:20
83
233
  services:
84
234
  - docker:dind
235
+ variables:
236
+ DOCKER_HOST: tcp://docker:2375
85
237
  script:
86
238
  - npx tc-scanner scan ./Dockerfile --severity HIGH
87
239
  - npx tc-scanner deps . --severity HIGH
240
+ - npx tc-scanner secrets ./src
241
+ artifacts:
242
+ paths:
243
+ - reports/
244
+ when: always
245
+ ```
246
+
247
+ ### CircleCI
248
+
249
+ ```yaml
250
+ version: 2.1
251
+
252
+ jobs:
253
+ security-scan:
254
+ docker:
255
+ - image: cimg/node:20.0
256
+ steps:
257
+ - checkout
258
+ - setup_remote_docker
259
+ - run:
260
+ name: Security Scan
261
+ command: |
262
+ npx tc-scanner scan ./Dockerfile --severity HIGH
263
+ npx tc-scanner deps . --severity HIGH
264
+
265
+ workflows:
266
+ main:
267
+ jobs:
268
+ - security-scan
88
269
  ```
89
270
 
90
- ## CLI Options
271
+ ## Exit Codes
272
+
273
+ | Code | Meaning |
274
+ |------|---------|
275
+ | `0` | No issues found (or below severity threshold) |
276
+ | `1` | Issues found at or above severity threshold |
91
277
 
278
+ Use `--exit-code 0` to always pass (useful for non-blocking scans):
279
+
280
+ ```bash
281
+ npx tc-scanner scan ./Dockerfile --exit-code 0
92
282
  ```
93
- Usage: tc-scan [command] [options]
94
283
 
95
- Commands:
96
- scan [path] Scan a Dockerfile
97
- deps [path] Scan project dependencies
98
- secrets [path] Scan for secrets in code
99
- image <name> Scan a container image
284
+ ## Severity Levels
285
+
286
+ | Level | Description |
287
+ |-------|-------------|
288
+ | `CRITICAL` | Severe vulnerabilities requiring immediate action |
289
+ | `HIGH` | Important security issues that should be fixed soon |
290
+ | `MEDIUM` | Moderate issues to address in regular maintenance |
291
+ | `LOW` | Minor issues or best practice recommendations |
100
292
 
101
- Options:
102
- -s, --severity Minimum severity: LOW, MEDIUM, HIGH, CRITICAL (default: HIGH)
103
- -o, --output Save report to file (generates .json, .txt, .html)
104
- --exit-code Exit code when issues found (default: 1)
105
- --include-dev Include dev dependencies in scan
293
+ ## Examples
294
+
295
+ **Fail CI only on critical issues:**
296
+ ```bash
297
+ npx tc-scanner scan ./Dockerfile --severity CRITICAL
106
298
  ```
107
299
 
108
- ## Generate Reports
300
+ **Full security audit with reports:**
301
+ ```bash
302
+ npx tc-scanner scan ./Dockerfile --output ./reports/dockerfile --severity LOW
303
+ npx tc-scanner deps . --output ./reports/deps --severity LOW --include-dev
304
+ npx tc-scanner secrets ./src --output ./reports/secrets
305
+ ```
109
306
 
307
+ **Send alerts to Slack on failures:**
110
308
  ```bash
111
- # Generates scan-report.json, scan-report.txt, scan-report.html
112
- npx tc-scanner scan ./Dockerfile --output ./reports/scan-report
309
+ npx tc-scanner scan ./Dockerfile --webhook $SLACK_WEBHOOK_URL
113
310
  ```
114
311
 
115
- Reports can be:
116
- - Attached to CI artifacts
117
- - Sent via email
118
- - Posted to Slack/webhooks
312
+ ## Troubleshooting
313
+
314
+ **"Docker is required"**
315
+ - Ensure Docker is installed and running
316
+ - In CI, enable the Docker service (see examples above)
119
317
 
120
- ## What It Detects
318
+ **"No lockfile found" (deps command)**
319
+ - The scanner needs `package-lock.json`, `yarn.lock`, or similar
320
+ - Run `npm install` or your package manager to generate a lockfile
121
321
 
122
- | Scan Type | Detects |
123
- |-----------|---------|
124
- | `scan` | Dockerfile misconfigurations (missing HEALTHCHECK, running as root, etc.) |
125
- | `deps` | Known CVEs in npm/yarn/pnpm packages |
126
- | `secrets` | API keys, tokens, passwords, private keys in code |
127
- | `image` | OS package vulnerabilities + app dependencies in containers |
322
+ **Slow first run**
323
+ - First run downloads the Trivy Docker image (~50MB) and vulnerability database (~80MB)
324
+ - Subsequent runs are faster due to caching
128
325
 
129
326
  ## License
130
327
 
package/bin/cli.js CHANGED
@@ -6,128 +6,239 @@ import { scanDockerfile, scanImage, scanFilesystem, sendWebhook } from '../src/s
6
6
  const main = defineCommand({
7
7
  meta: {
8
8
  name: 'tc-scan',
9
- version: '0.1.0',
10
- description: 'CI security scanner for Dockerfiles, dependencies, and secrets. Requires Docker.',
9
+ version: '0.1.1',
10
+ description: 'CI security scanner for Dockerfiles, images, dependencies, and secrets.\n\nRequires Docker. Powered by Trivy.',
11
11
  },
12
12
  subCommands: {
13
13
  scan: defineCommand({
14
- meta: { description: 'Scan a Dockerfile for misconfigurations' },
14
+ meta: {
15
+ name: 'scan',
16
+ description: 'Scan a Dockerfile for security misconfigurations.\n\nDetects: running as root, missing HEALTHCHECK, unpinned versions, insecure ADD, and more.',
17
+ },
15
18
  args: {
16
- path: { type: 'positional', description: 'Path to Dockerfile', default: './Dockerfile' },
17
- severity: { type: 'string', alias: 's', description: 'Minimum severity (LOW, MEDIUM, HIGH, CRITICAL)', default: 'HIGH' },
18
- output: { type: 'string', alias: 'o', description: 'Save report to file (generates .json, .txt, .html)' },
19
- webhook: { type: 'string', alias: 'w', description: 'Send results to webhook URL' },
20
- 'exit-code': { type: 'string', description: 'Exit code when issues found', default: '1' },
19
+ path: {
20
+ type: 'positional',
21
+ description: 'Path to Dockerfile',
22
+ default: './Dockerfile',
23
+ },
24
+ severity: {
25
+ type: 'string',
26
+ alias: 's',
27
+ description: 'Minimum severity to report (LOW, MEDIUM, HIGH, CRITICAL)',
28
+ default: 'HIGH',
29
+ },
30
+ output: {
31
+ type: 'string',
32
+ alias: 'o',
33
+ description: 'Save report to file (creates .json, .txt, .html)',
34
+ },
35
+ webhook: {
36
+ type: 'string',
37
+ alias: 'w',
38
+ description: 'Send results to webhook URL (Slack, custom endpoint)',
39
+ },
40
+ 'exit-code': {
41
+ type: 'string',
42
+ description: 'Exit code when issues found (use 0 to never fail)',
43
+ default: '1',
44
+ },
21
45
  },
22
46
  async run({ args }) {
23
- console.log(''.repeat(50));
24
- console.log(' TC-Secure Scanner');
25
- console.log('━'.repeat(50));
26
- console.log();
27
-
28
- const result = await scanDockerfile(args.path, {
29
- severity: args.severity,
30
- output: args.output,
31
- exitCode: args['exit-code'],
32
- });
33
-
34
- if (args.webhook && result.json) {
35
- await sendWebhook(args.webhook, result.json, 'dockerfile');
47
+ printHeader('Dockerfile Scanner');
48
+
49
+ try {
50
+ const result = await scanDockerfile(args.path, {
51
+ severity: args.severity,
52
+ output: args.output,
53
+ exitCode: args['exit-code'],
54
+ });
55
+
56
+ if (args.webhook && result.json) {
57
+ await sendWebhook(args.webhook, result.json, 'dockerfile');
58
+ }
59
+
60
+ process.exit(result.exitCode);
61
+ } catch (error) {
62
+ console.error(`\nError: ${error.message}`);
63
+ process.exit(1);
36
64
  }
37
-
38
- process.exit(result.exitCode);
39
65
  },
40
66
  }),
41
67
 
42
68
  image: defineCommand({
43
- meta: { description: 'Scan a container image for vulnerabilities' },
69
+ meta: {
70
+ name: 'image',
71
+ description: 'Scan a container image for vulnerabilities.\n\nDetects: OS package CVEs, application dependency vulnerabilities, embedded secrets.',
72
+ },
44
73
  args: {
45
- image: { type: 'positional', description: 'Image name (e.g., nginx:latest)', required: true },
46
- severity: { type: 'string', alias: 's', description: 'Minimum severity', default: 'HIGH' },
47
- output: { type: 'string', alias: 'o', description: 'Save report to file' },
48
- webhook: { type: 'string', alias: 'w', description: 'Send results to webhook URL' },
49
- 'exit-code': { type: 'string', description: 'Exit code when issues found', default: '1' },
74
+ image: {
75
+ type: 'positional',
76
+ description: 'Image name (e.g., nginx:latest, myapp:v1.2.3)',
77
+ required: true,
78
+ },
79
+ severity: {
80
+ type: 'string',
81
+ alias: 's',
82
+ description: 'Minimum severity to report (LOW, MEDIUM, HIGH, CRITICAL)',
83
+ default: 'HIGH',
84
+ },
85
+ output: {
86
+ type: 'string',
87
+ alias: 'o',
88
+ description: 'Save report to file (creates .json, .txt, .html)',
89
+ },
90
+ webhook: {
91
+ type: 'string',
92
+ alias: 'w',
93
+ description: 'Send results to webhook URL',
94
+ },
95
+ 'exit-code': {
96
+ type: 'string',
97
+ description: 'Exit code when issues found',
98
+ default: '1',
99
+ },
50
100
  },
51
101
  async run({ args }) {
52
- console.log(''.repeat(50));
53
- console.log(' TC-Secure Image Scanner');
54
- console.log('━'.repeat(50));
55
- console.log();
56
-
57
- const result = await scanImage(args.image, {
58
- severity: args.severity,
59
- output: args.output,
60
- exitCode: args['exit-code'],
61
- });
62
-
63
- if (args.webhook && result.json) {
64
- await sendWebhook(args.webhook, result.json, 'image');
102
+ printHeader('Image Scanner');
103
+
104
+ try {
105
+ const result = await scanImage(args.image, {
106
+ severity: args.severity,
107
+ output: args.output,
108
+ exitCode: args['exit-code'],
109
+ });
110
+
111
+ if (args.webhook && result.json) {
112
+ await sendWebhook(args.webhook, result.json, 'image');
113
+ }
114
+
115
+ process.exit(result.exitCode);
116
+ } catch (error) {
117
+ console.error(`\nError: ${error.message}`);
118
+ process.exit(1);
65
119
  }
66
-
67
- process.exit(result.exitCode);
68
120
  },
69
121
  }),
70
122
 
71
123
  deps: defineCommand({
72
- meta: { description: 'Scan project dependencies (package-lock.json, yarn.lock, etc.)' },
124
+ meta: {
125
+ name: 'deps',
126
+ description: 'Scan project dependencies for known vulnerabilities (CVEs).\n\nSupports: npm, yarn, pnpm, pip, bundler, composer, go modules.',
127
+ },
73
128
  args: {
74
- path: { type: 'positional', description: 'Path to project directory', default: '.' },
75
- severity: { type: 'string', alias: 's', description: 'Minimum severity', default: 'HIGH' },
76
- output: { type: 'string', alias: 'o', description: 'Save report to file' },
77
- webhook: { type: 'string', alias: 'w', description: 'Send results to webhook URL' },
78
- 'exit-code': { type: 'string', description: 'Exit code when issues found', default: '1' },
79
- 'include-dev': { type: 'boolean', description: 'Include dev dependencies', default: false },
129
+ path: {
130
+ type: 'positional',
131
+ description: 'Path to project directory containing lockfile',
132
+ default: '.',
133
+ },
134
+ severity: {
135
+ type: 'string',
136
+ alias: 's',
137
+ description: 'Minimum severity to report (LOW, MEDIUM, HIGH, CRITICAL)',
138
+ default: 'HIGH',
139
+ },
140
+ output: {
141
+ type: 'string',
142
+ alias: 'o',
143
+ description: 'Save report to file (creates .json, .txt, .html)',
144
+ },
145
+ webhook: {
146
+ type: 'string',
147
+ alias: 'w',
148
+ description: 'Send results to webhook URL',
149
+ },
150
+ 'exit-code': {
151
+ type: 'string',
152
+ description: 'Exit code when issues found',
153
+ default: '1',
154
+ },
155
+ 'include-dev': {
156
+ type: 'boolean',
157
+ description: 'Include development dependencies in scan',
158
+ default: false,
159
+ },
80
160
  },
81
161
  async run({ args }) {
82
- console.log(''.repeat(50));
83
- console.log(' TC-Secure Dependency Scanner');
84
- console.log('━'.repeat(50));
85
- console.log();
86
-
87
- const result = await scanFilesystem(args.path, {
88
- severity: args.severity,
89
- output: args.output,
90
- exitCode: args['exit-code'],
91
- includeDev: args['include-dev'],
92
- scanType: 'vuln',
93
- });
94
-
95
- if (args.webhook && result.json) {
96
- await sendWebhook(args.webhook, result.json, 'dependencies');
162
+ printHeader('Dependency Scanner');
163
+
164
+ try {
165
+ const result = await scanFilesystem(args.path, {
166
+ severity: args.severity,
167
+ output: args.output,
168
+ exitCode: args['exit-code'],
169
+ includeDev: args['include-dev'],
170
+ scanType: 'vuln',
171
+ });
172
+
173
+ if (args.webhook && result.json) {
174
+ await sendWebhook(args.webhook, result.json, 'dependencies');
175
+ }
176
+
177
+ process.exit(result.exitCode);
178
+ } catch (error) {
179
+ console.error(`\nError: ${error.message}`);
180
+ process.exit(1);
97
181
  }
98
-
99
- process.exit(result.exitCode);
100
182
  },
101
183
  }),
102
184
 
103
185
  secrets: defineCommand({
104
- meta: { description: 'Scan for secrets and sensitive data in code' },
186
+ meta: {
187
+ name: 'secrets',
188
+ description: 'Scan code for hardcoded secrets and sensitive data.\n\nDetects: API keys, tokens, passwords, private keys, connection strings.',
189
+ },
105
190
  args: {
106
- path: { type: 'positional', description: 'Path to project directory', default: '.' },
107
- output: { type: 'string', alias: 'o', description: 'Save report to file' },
108
- webhook: { type: 'string', alias: 'w', description: 'Send results to webhook URL' },
109
- 'exit-code': { type: 'string', description: 'Exit code when secrets found', default: '1' },
191
+ path: {
192
+ type: 'positional',
193
+ description: 'Path to directory to scan',
194
+ default: '.',
195
+ },
196
+ output: {
197
+ type: 'string',
198
+ alias: 'o',
199
+ description: 'Save report to file (creates .json, .txt, .html)',
200
+ },
201
+ webhook: {
202
+ type: 'string',
203
+ alias: 'w',
204
+ description: 'Send results to webhook URL',
205
+ },
206
+ 'exit-code': {
207
+ type: 'string',
208
+ description: 'Exit code when secrets found',
209
+ default: '1',
210
+ },
110
211
  },
111
212
  async run({ args }) {
112
- console.log(''.repeat(50));
113
- console.log(' TC-Secure Secrets Scanner');
114
- console.log('━'.repeat(50));
115
- console.log();
116
-
117
- const result = await scanFilesystem(args.path, {
118
- output: args.output,
119
- exitCode: args['exit-code'],
120
- scanType: 'secret',
121
- });
122
-
123
- if (args.webhook && result.json) {
124
- await sendWebhook(args.webhook, result.json, 'secrets');
213
+ printHeader('Secrets Scanner');
214
+
215
+ try {
216
+ const result = await scanFilesystem(args.path, {
217
+ output: args.output,
218
+ exitCode: args['exit-code'],
219
+ scanType: 'secret',
220
+ });
221
+
222
+ if (args.webhook && result.json) {
223
+ await sendWebhook(args.webhook, result.json, 'secrets');
224
+ }
225
+
226
+ process.exit(result.exitCode);
227
+ } catch (error) {
228
+ console.error(`\nError: ${error.message}`);
229
+ process.exit(1);
125
230
  }
126
-
127
- process.exit(result.exitCode);
128
231
  },
129
232
  }),
130
233
  },
131
234
  });
132
235
 
236
+ function printHeader(title) {
237
+ console.log();
238
+ console.log('━'.repeat(50));
239
+ console.log(` TC-Secure ${title}`);
240
+ console.log('━'.repeat(50));
241
+ console.log();
242
+ }
243
+
133
244
  runMain(main);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tc-scanner",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CI security scanner for Dockerfiles, dependencies, and secrets using Trivy",
5
5
  "type": "module",
6
6
  "bin": {
package/.env DELETED
@@ -1 +0,0 @@
1
- NPM_TOKEN=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
@@ -1,61 +0,0 @@
1
-
2
- <!DOCTYPE html>
3
- <html>
4
- <head>
5
- <style>
6
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
7
- .header { background: #1e293b; color: white; padding: 20px; border-radius: 8px 8px 0 0; }
8
- .content { border: 1px solid #e2e8f0; border-top: none; padding: 20px; border-radius: 0 0 8px 8px; }
9
- .summary-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 20px 0; }
10
- .stat { text-align: center; padding: 15px; border-radius: 8px; }
11
- .stat-critical { background: #fef2f2; border: 1px solid #fecaca; }
12
- .stat-high { background: #fff7ed; border: 1px solid #fed7aa; }
13
- .stat-medium { background: #fefce8; border: 1px solid #fef08a; }
14
- .stat-low { background: #eff6ff; border: 1px solid #bfdbfe; }
15
- .stat-value { font-size: 24px; font-weight: bold; }
16
- .issue { border-left: 4px solid; padding: 12px; margin: 10px 0; background: #f8fafc; }
17
- .issue-critical { border-color: #dc2626; }
18
- .issue-high { border-color: #ea580c; }
19
- .issue-medium { border-color: #ca8a04; }
20
- .issue-low { border-color: #2563eb; }
21
- .badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; color: white; }
22
- a { color: #2563eb; }
23
- </style>
24
- </head>
25
- <body>
26
- <div class="header">
27
- <h1 style="margin: 0;">TC-Secure Scan Report</h1>
28
- <p style="margin: 5px 0 0 0; opacity: 0.8;">Target: /Users/themba/Teamcoda/teamcoda/tc-secure/pentest/Dockerfile</p>
29
- <p style="margin: 5px 0 0 0; opacity: 0.8;">Scan Time: 2026-02-02T00:06:36.733Z</p>
30
- </div>
31
- <div class="content">
32
- <h2>Summary</h2>
33
- <div class="summary-grid">
34
- <div class="stat stat-critical">
35
- <div class="stat-value" style="color: #dc2626">0</div>
36
- <div>Critical</div>
37
- </div>
38
- <div class="stat stat-high">
39
- <div class="stat-value" style="color: #ea580c">0</div>
40
- <div>High</div>
41
- </div>
42
- <div class="stat stat-medium">
43
- <div class="stat-value" style="color: #ca8a04">0</div>
44
- <div>Medium</div>
45
- </div>
46
- <div class="stat stat-low">
47
- <div class="stat-value" style="color: #2563eb">1</div>
48
- <div>Low</div>
49
- </div>
50
- </div>
51
- <h2>Issues (1)</h2>
52
- <div class="issue issue-low">
53
- <span class="badge" style="background: #2563eb">LOW</span>
54
- <strong>DS-0026</strong>
55
- <p style="margin: 8px 0;">No HEALTHCHECK defined</p>
56
-
57
- <a href="https://avd.aquasec.com/misconfig/ds-0026" style="font-size: 14px;">View details →</a>
58
- </div>
59
- </div>
60
- </body>
61
- </html>
@@ -1,21 +0,0 @@
1
- {
2
- "target": "/Users/themba/Teamcoda/teamcoda/tc-secure/pentest/Dockerfile",
3
- "scanTime": "2026-02-02T00:06:36.733Z",
4
- "totalIssues": 1,
5
- "bySeverity": {
6
- "CRITICAL": 0,
7
- "HIGH": 0,
8
- "MEDIUM": 0,
9
- "LOW": 1
10
- },
11
- "issues": [
12
- {
13
- "id": "DS-0026",
14
- "severity": "LOW",
15
- "title": "No HEALTHCHECK defined",
16
- "description": "You should add HEALTHCHECK instruction in your docker container images to perform the health check on running containers.",
17
- "resolution": "Add HEALTHCHECK instruction in Dockerfile",
18
- "url": "https://avd.aquasec.com/misconfig/ds-0026"
19
- }
20
- ]
21
- }
@@ -1,20 +0,0 @@
1
-
2
- TC-SECURE SCAN REPORT
3
- =====================
4
- Target: /Users/themba/Teamcoda/teamcoda/tc-secure/pentest/Dockerfile
5
- Scan Time: 2026-02-02T00:06:36.733Z
6
-
7
- SUMMARY
8
- -------
9
- Total Issues: 1
10
- CRITICAL: 0
11
- HIGH: 0
12
- MEDIUM: 0
13
- LOW: 1
14
-
15
- DETAILS
16
- -------
17
-
18
- [LOW] DS-0026
19
- No HEALTHCHECK defined
20
- More info: https://avd.aquasec.com/misconfig/ds-0026