@mitre/hdf-generators 2.0.0
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/LICENSE.md +55 -0
- package/README.md +82 -0
- package/dist/control-stub.d.ts +16 -0
- package/dist/control-stub.d.ts.map +1 -0
- package/dist/control-stub.js +81 -0
- package/dist/control-stub.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/inspec-yml.d.ts +10 -0
- package/dist/inspec-yml.d.ts.map +1 -0
- package/dist/inspec-yml.js +113 -0
- package/dist/inspec-yml.js.map +1 -0
- package/dist/profile-generator.d.ts +11 -0
- package/dist/profile-generator.d.ts.map +1 -0
- package/dist/profile-generator.js +31 -0
- package/dist/profile-generator.js.map +1 -0
- package/dist/ruby-escape.d.ts +13 -0
- package/dist/ruby-escape.d.ts.map +1 -0
- package/dist/ruby-escape.js +26 -0
- package/dist/ruby-escape.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
Copyright © 2025 The MITRE Corporation.
|
|
4
|
+
|
|
5
|
+
Approved for Public Release; Distribution Unlimited. Case Number 18-3678.
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
8
|
+
not use this file except in compliance with the License. You may obtain a
|
|
9
|
+
copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
15
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
16
|
+
License for the specific language governing permissions and limitations
|
|
17
|
+
under the License.
|
|
18
|
+
|
|
19
|
+
## Redistribution Terms
|
|
20
|
+
|
|
21
|
+
Redistribution and use in source and binary forms, with or without
|
|
22
|
+
modification, are permitted provided that the following conditions are
|
|
23
|
+
met:
|
|
24
|
+
|
|
25
|
+
- Redistributions of source code must retain the above copyright/digital
|
|
26
|
+
rights legend, this list of conditions and the following Notice.
|
|
27
|
+
- Redistributions in binary form must reproduce the above
|
|
28
|
+
copyright/digital rights legend, this list of conditions and the
|
|
29
|
+
following Notice in the documentation and/or other materials provided
|
|
30
|
+
with the distribution.
|
|
31
|
+
- Neither the name of The MITRE Corporation nor the names of its contributors
|
|
32
|
+
may be used to endorse or promote products derived from this software
|
|
33
|
+
without specific prior written permission.
|
|
34
|
+
|
|
35
|
+
## Notice
|
|
36
|
+
|
|
37
|
+
The MITRE Corporation grants permission to reproduce, distribute, modify, and
|
|
38
|
+
otherwise use this software to the extent permitted by the licensed terms
|
|
39
|
+
provided in the LICENSE file included with this project.
|
|
40
|
+
|
|
41
|
+
This software was produced by The MITRE Corporation for the U.S. Government
|
|
42
|
+
under contract. As such the U.S. Government has certain use and data
|
|
43
|
+
rights in this software. No use other than those granted to the U.S.
|
|
44
|
+
Government, or to those acting on behalf of the U.S. Government, under
|
|
45
|
+
these contract arrangements is authorized without the express written
|
|
46
|
+
permission of The MITRE Corporation.
|
|
47
|
+
|
|
48
|
+
Some files in this codebase were generated by generative AI, under the
|
|
49
|
+
direction and review of The MITRE Corporation employees, for the purpose of
|
|
50
|
+
development efficiency. All AI-generated code functionality was validated
|
|
51
|
+
by standard quality and assurance testing.
|
|
52
|
+
|
|
53
|
+
For further information, please contact The MITRE Corporation,
|
|
54
|
+
Contracts Management Office, 7515 Colshire Drive, McLean, VA 22102-7539,
|
|
55
|
+
(703) 983-6000.
|
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @mitre/hdf-generators
|
|
2
|
+
|
|
3
|
+
Generate InSpec profile stubs from HDF Baseline definitions.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
Takes an HDF Baseline JSON document (requirement definitions with metadata, descriptions, and tags) and generates a complete InSpec profile directory structure:
|
|
8
|
+
|
|
9
|
+
- `inspec.yml` — profile metadata (name, maintainer, license, version, platform supports)
|
|
10
|
+
- `controls/*.rb` — one control file per requirement with `describe` blocks, tags, and impact
|
|
11
|
+
|
|
12
|
+
This bridges from HDF's tool-agnostic baseline format to InSpec's executable compliance-as-code format.
|
|
13
|
+
|
|
14
|
+
## Relationship to other packages
|
|
15
|
+
|
|
16
|
+
| Package | Relationship |
|
|
17
|
+
|---------|-------------|
|
|
18
|
+
| **hdf-schema** | Provides the `HDFBaseline` type that generators consume |
|
|
19
|
+
| **hdf-converters** | Converters produce baselines (e.g., XCCDF benchmark → HDF baseline) that generators can then turn into InSpec profiles |
|
|
20
|
+
| **hdf-cli** | `hdf generate inspec-profile` command wraps this library |
|
|
21
|
+
| **hdf-mappings** | Baselines may contain NIST/CCI tags from hdf-mappings |
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @mitre/hdf-generators
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Usage (TypeScript)
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { generateInSpecProfile } from '@mitre/hdf-generators';
|
|
33
|
+
import type { HDFBaseline } from '@mitre/hdf-schema';
|
|
34
|
+
|
|
35
|
+
const baseline: HDFBaseline = JSON.parse(fs.readFileSync('baseline.json', 'utf8'));
|
|
36
|
+
|
|
37
|
+
const profile = generateInSpecProfile(baseline, {
|
|
38
|
+
maintainer: 'MITRE SAF',
|
|
39
|
+
copyright: 'MITRE Corporation',
|
|
40
|
+
license: 'Apache-2.0',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// profile.inspecYml — string content for inspec.yml
|
|
44
|
+
// profile.controls — Map<string, string> of filename → Ruby control code
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Individual stubs
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { generateControlStub, generateInSpecYml, escapeQuotes } from '@mitre/hdf-generators';
|
|
51
|
+
|
|
52
|
+
// Generate a single control file
|
|
53
|
+
const ruby = generateControlStub(requirement);
|
|
54
|
+
|
|
55
|
+
// Generate inspec.yml
|
|
56
|
+
const yml = generateInSpecYml(baseline, { maintainer: 'Team', license: 'Apache-2.0' });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Usage (Go)
|
|
60
|
+
|
|
61
|
+
```go
|
|
62
|
+
import generators "github.com/mitre/hdf-generators"
|
|
63
|
+
|
|
64
|
+
profile := generators.GenerateInSpecProfile(baseline, generators.ProfileMetadata{
|
|
65
|
+
Maintainer: "MITRE SAF",
|
|
66
|
+
License: "Apache-2.0",
|
|
67
|
+
})
|
|
68
|
+
// profile.InspecYml — string
|
|
69
|
+
// profile.Controls — map[string]string
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## CLI usage
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
hdf generate inspec-profile baseline.json output-dir/
|
|
76
|
+
hdf generate inspec-profile baseline.json output-dir/ --maintainer "MITRE SAF"
|
|
77
|
+
hdf generate inspec-profile baseline.json output-dir/ --single-file
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
Apache-2.0 © MITRE Corporation
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BaselineRequirement } from '@mitre/hdf-schema';
|
|
2
|
+
/**
|
|
3
|
+
* Generate a Ruby InSpec control stub from an HDF BaselineRequirement.
|
|
4
|
+
*
|
|
5
|
+
* Output follows the InSpec DSL ordering convention:
|
|
6
|
+
* control 'ID' do
|
|
7
|
+
* title ...
|
|
8
|
+
* desc ...
|
|
9
|
+
* desc 'check', ...
|
|
10
|
+
* impact ...
|
|
11
|
+
* tag key: value
|
|
12
|
+
* <code or stub comment>
|
|
13
|
+
* end
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateControlStub(req: BaselineRequirement): string;
|
|
16
|
+
//# sourceMappingURL=control-stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-stub.d.ts","sourceRoot":"","sources":["../src/control-stub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAG7D;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAsDpE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { escapeQuotes } from './ruby-escape.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generate a Ruby InSpec control stub from an HDF BaselineRequirement.
|
|
4
|
+
*
|
|
5
|
+
* Output follows the InSpec DSL ordering convention:
|
|
6
|
+
* control 'ID' do
|
|
7
|
+
* title ...
|
|
8
|
+
* desc ...
|
|
9
|
+
* desc 'check', ...
|
|
10
|
+
* impact ...
|
|
11
|
+
* tag key: value
|
|
12
|
+
* <code or stub comment>
|
|
13
|
+
* end
|
|
14
|
+
*/
|
|
15
|
+
export function generateControlStub(req) {
|
|
16
|
+
const lines = [];
|
|
17
|
+
lines.push(`control '${req.id}' do`);
|
|
18
|
+
// Title
|
|
19
|
+
if (req.title) {
|
|
20
|
+
lines.push(` title ${escapeQuotes(req.title)}`);
|
|
21
|
+
}
|
|
22
|
+
// Descriptions: default first (as bare `desc`), then labeled
|
|
23
|
+
const defaultDesc = req.descriptions.find((d) => d.label === 'default');
|
|
24
|
+
if (defaultDesc) {
|
|
25
|
+
lines.push(` desc ${escapeQuotes(defaultDesc.data)}`);
|
|
26
|
+
}
|
|
27
|
+
const seenDefault = new Set();
|
|
28
|
+
for (const d of req.descriptions) {
|
|
29
|
+
if (d.label === 'default') {
|
|
30
|
+
if (seenDefault.has('default')) {
|
|
31
|
+
continue; // skip duplicate default
|
|
32
|
+
}
|
|
33
|
+
seenDefault.add('default');
|
|
34
|
+
continue; // already emitted above as bare desc
|
|
35
|
+
}
|
|
36
|
+
lines.push(` desc '${d.label}', ${escapeQuotes(d.data)}`);
|
|
37
|
+
}
|
|
38
|
+
// Impact — always render with at least one decimal place for 0 and whole numbers
|
|
39
|
+
if (req.impact !== undefined) {
|
|
40
|
+
const impactStr = Number.isInteger(req.impact)
|
|
41
|
+
? req.impact.toFixed(1)
|
|
42
|
+
: String(req.impact);
|
|
43
|
+
lines.push(` impact ${impactStr}`);
|
|
44
|
+
}
|
|
45
|
+
// Tags
|
|
46
|
+
for (const [key, value] of Object.entries(req.tags)) {
|
|
47
|
+
lines.push(` ${formatTag(key, value)}`);
|
|
48
|
+
}
|
|
49
|
+
// Code body or stub placeholder
|
|
50
|
+
if (req.code) {
|
|
51
|
+
lines.push('');
|
|
52
|
+
lines.push(req.code);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
lines.push('');
|
|
56
|
+
lines.push(' # TODO: Add InSpec test code here');
|
|
57
|
+
}
|
|
58
|
+
lines.push('end');
|
|
59
|
+
lines.push(''); // trailing newline
|
|
60
|
+
return lines.join('\n');
|
|
61
|
+
}
|
|
62
|
+
/** Format a single tag key-value pair as Ruby DSL. */
|
|
63
|
+
function formatTag(key, value) {
|
|
64
|
+
if (value === null || value === undefined) {
|
|
65
|
+
return `tag ${key}: nil`;
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(value)) {
|
|
68
|
+
// Ruby array syntax: tag key: ['val1', 'val2']
|
|
69
|
+
const items = value.map((v) => `'${String(v)}'`).join(', ');
|
|
70
|
+
return `tag ${key}: [${items}]`;
|
|
71
|
+
}
|
|
72
|
+
if (typeof value === 'boolean') {
|
|
73
|
+
return `tag ${key}: ${value}`;
|
|
74
|
+
}
|
|
75
|
+
if (typeof value === 'string') {
|
|
76
|
+
return `tag ${key}: ${escapeQuotes(value)}`;
|
|
77
|
+
}
|
|
78
|
+
// Fallback for other types (numbers, objects)
|
|
79
|
+
return `tag ${key}: ${JSON.stringify(value)}`;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=control-stub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-stub.js","sourceRoot":"","sources":["../src/control-stub.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { GeneratorOptions, ProfileMetadata, InSpecProfile } from './types.js';
|
|
2
|
+
export { escapeQuotes } from './ruby-escape.js';
|
|
3
|
+
export { generateControlStub } from './control-stub.js';
|
|
4
|
+
export { generateInSpecYml } from './inspec-yml.js';
|
|
5
|
+
export { generateInSpecProfile } from './profile-generator.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HdfBaseline } from '@mitre/hdf-schema';
|
|
2
|
+
import type { GeneratorOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate an inspec.yml YAML string from an HDF Baseline and options.
|
|
5
|
+
*
|
|
6
|
+
* Uses string interpolation — no YAML library needed since the structure
|
|
7
|
+
* is fixed and shallow.
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateInSpecYml(baseline: HdfBaseline, options?: GeneratorOptions): string;
|
|
10
|
+
//# sourceMappingURL=inspec-yml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspec-yml.d.ts","sourceRoot":"","sources":["../src/inspec-yml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAoGR"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate an inspec.yml YAML string from an HDF Baseline and options.
|
|
3
|
+
*
|
|
4
|
+
* Uses string interpolation — no YAML library needed since the structure
|
|
5
|
+
* is fixed and shallow.
|
|
6
|
+
*/
|
|
7
|
+
export function generateInSpecYml(baseline, options) {
|
|
8
|
+
const lines = [];
|
|
9
|
+
const meta = options?.metadata;
|
|
10
|
+
// Required: name
|
|
11
|
+
lines.push(`name: ${baseline.name}`);
|
|
12
|
+
// Optional metadata fields
|
|
13
|
+
if (baseline.title) {
|
|
14
|
+
lines.push(`title: ${baseline.title}`);
|
|
15
|
+
}
|
|
16
|
+
const maintainer = meta?.maintainer ?? baseline.maintainer;
|
|
17
|
+
if (maintainer) {
|
|
18
|
+
lines.push(`maintainer: ${maintainer}`);
|
|
19
|
+
}
|
|
20
|
+
const copyright = meta?.copyright ?? baseline.copyright;
|
|
21
|
+
if (copyright) {
|
|
22
|
+
lines.push(`copyright: ${copyright}`);
|
|
23
|
+
}
|
|
24
|
+
const license = meta?.license ?? baseline.license;
|
|
25
|
+
if (license) {
|
|
26
|
+
lines.push(`license: ${license}`);
|
|
27
|
+
}
|
|
28
|
+
if (baseline.summary) {
|
|
29
|
+
lines.push(`summary: ${baseline.summary}`);
|
|
30
|
+
}
|
|
31
|
+
// Version: metadata override takes priority
|
|
32
|
+
const version = meta?.version ?? baseline.version;
|
|
33
|
+
if (version) {
|
|
34
|
+
lines.push(`version: '${version}'`);
|
|
35
|
+
}
|
|
36
|
+
// InSpec version constraint
|
|
37
|
+
const inspecVersion = options?.inspecVersion ?? '~>6.0';
|
|
38
|
+
lines.push(`inspec_version: '${inspecVersion}'`);
|
|
39
|
+
// Supports array
|
|
40
|
+
if (baseline.supports && baseline.supports.length > 0) {
|
|
41
|
+
lines.push('supports:');
|
|
42
|
+
for (const support of baseline.supports) {
|
|
43
|
+
const entries = [];
|
|
44
|
+
if (support.platformName) {
|
|
45
|
+
entries.push(` platform-name: ${support.platformName}`);
|
|
46
|
+
}
|
|
47
|
+
if (support.platformFamily) {
|
|
48
|
+
entries.push(` platform-family: ${support.platformFamily}`);
|
|
49
|
+
}
|
|
50
|
+
if (support.platform) {
|
|
51
|
+
entries.push(` platform: ${support.platform}`);
|
|
52
|
+
}
|
|
53
|
+
if (support.release) {
|
|
54
|
+
entries.push(` release: ${support.release}`);
|
|
55
|
+
}
|
|
56
|
+
if (entries.length > 0) {
|
|
57
|
+
lines.push(`- ${entries[0].trimStart()}`);
|
|
58
|
+
for (let i = 1; i < entries.length; i++) {
|
|
59
|
+
lines.push(entries[i]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Depends array
|
|
65
|
+
if (baseline.depends && baseline.depends.length > 0) {
|
|
66
|
+
lines.push('depends:');
|
|
67
|
+
for (const dep of baseline.depends) {
|
|
68
|
+
const entries = [];
|
|
69
|
+
if (dep.name)
|
|
70
|
+
entries.push(`name: ${dep.name}`);
|
|
71
|
+
if (dep.git)
|
|
72
|
+
entries.push(`git: ${dep.git}`);
|
|
73
|
+
if (dep.url)
|
|
74
|
+
entries.push(`url: ${dep.url}`);
|
|
75
|
+
if (dep.path)
|
|
76
|
+
entries.push(`path: ${dep.path}`);
|
|
77
|
+
if (dep.branch)
|
|
78
|
+
entries.push(`branch: ${dep.branch}`);
|
|
79
|
+
if (dep.compliance)
|
|
80
|
+
entries.push(`compliance: ${dep.compliance}`);
|
|
81
|
+
if (dep.supermarket)
|
|
82
|
+
entries.push(`supermarket: ${dep.supermarket}`);
|
|
83
|
+
if (entries.length > 0) {
|
|
84
|
+
lines.push(`- ${entries[0]}`);
|
|
85
|
+
for (let i = 1; i < entries.length; i++) {
|
|
86
|
+
lines.push(` ${entries[i]}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Inputs array
|
|
92
|
+
if (baseline.inputs && baseline.inputs.length > 0) {
|
|
93
|
+
lines.push('inputs:');
|
|
94
|
+
for (const input of baseline.inputs) {
|
|
95
|
+
for (const [key, value] of Object.entries(input)) {
|
|
96
|
+
lines.push(`- ${key}: ${formatYamlValue(value)}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
lines.push(''); // trailing newline
|
|
101
|
+
return lines.join('\n');
|
|
102
|
+
}
|
|
103
|
+
/** Format a value for inline YAML output. */
|
|
104
|
+
function formatYamlValue(value) {
|
|
105
|
+
if (typeof value === 'boolean')
|
|
106
|
+
return String(value);
|
|
107
|
+
if (typeof value === 'number')
|
|
108
|
+
return String(value);
|
|
109
|
+
if (typeof value === 'string')
|
|
110
|
+
return value;
|
|
111
|
+
return JSON.stringify(value);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=inspec-yml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspec-yml.js","sourceRoot":"","sources":["../src/inspec-yml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HdfBaseline } from '@mitre/hdf-schema';
|
|
2
|
+
import type { GeneratorOptions, InSpecProfile } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate an in-memory InSpec profile from an HDF Baseline.
|
|
5
|
+
*
|
|
6
|
+
* Returns an InSpecProfile with inspec.yml content and a Map of
|
|
7
|
+
* control filenames to Ruby source code. No file I/O — the CLI
|
|
8
|
+
* is responsible for writing files to disk.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateInSpecProfile(baseline: HdfBaseline, options?: GeneratorOptions): InSpecProfile;
|
|
11
|
+
//# sourceMappingURL=profile-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-generator.d.ts","sourceRoot":"","sources":["../src/profile-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIlE;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,gBAAgB,GACzB,aAAa,CAsBf"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { generateControlStub } from './control-stub.js';
|
|
2
|
+
import { generateInSpecYml } from './inspec-yml.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generate an in-memory InSpec profile from an HDF Baseline.
|
|
5
|
+
*
|
|
6
|
+
* Returns an InSpecProfile with inspec.yml content and a Map of
|
|
7
|
+
* control filenames to Ruby source code. No file I/O — the CLI
|
|
8
|
+
* is responsible for writing files to disk.
|
|
9
|
+
*/
|
|
10
|
+
export function generateInSpecProfile(baseline, options) {
|
|
11
|
+
const inspecYml = generateInSpecYml(baseline, options);
|
|
12
|
+
const controls = new Map();
|
|
13
|
+
if (baseline.requirements.length === 0) {
|
|
14
|
+
return { inspecYml, controls };
|
|
15
|
+
}
|
|
16
|
+
if (options?.singleFile) {
|
|
17
|
+
// All controls in a single file
|
|
18
|
+
const stubs = baseline.requirements.map((req) => generateControlStub(req));
|
|
19
|
+
controls.set('controls/controls.rb', stubs.join('\n'));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// One file per control — sanitize ID for safe filenames
|
|
23
|
+
for (const req of baseline.requirements) {
|
|
24
|
+
const safeId = req.id.replace(/\.\./g, '').replace(/[/\\]/g, '') || 'unknown';
|
|
25
|
+
const filename = `controls/${safeId}.rb`;
|
|
26
|
+
controls.set(filename, generateControlStub(req));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { inspecYml, controls };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=profile-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-generator.js","sourceRoot":"","sources":["../src/profile-generator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAqB,EACrB,OAA0B;IAE1B,MAAM,SAAS,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE3C,IAAI,QAAQ,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,gCAAgC;QAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,QAAQ,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,wDAAwD;QACxD,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;YAC9E,MAAM,QAAQ,GAAG,YAAY,MAAM,KAAK,CAAC;YACzC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escape a string for use as a Ruby string literal.
|
|
3
|
+
*
|
|
4
|
+
* Strategy:
|
|
5
|
+
* - If the string contains both single and double quotes → %q() wrapper
|
|
6
|
+
* - If the string contains only single quotes → double-quoted with escaping
|
|
7
|
+
* - Otherwise → single-quoted with escaping
|
|
8
|
+
*
|
|
9
|
+
* Ported from ts-inspec-objects escapeQuotes(), cross-referenced with
|
|
10
|
+
* inspec-parser's RubyRebuilder.
|
|
11
|
+
*/
|
|
12
|
+
export declare function escapeQuotes(s: string): string;
|
|
13
|
+
//# sourceMappingURL=ruby-escape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruby-escape.d.ts","sourceRoot":"","sources":["../src/ruby-escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB9C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escape a string for use as a Ruby string literal.
|
|
3
|
+
*
|
|
4
|
+
* Strategy:
|
|
5
|
+
* - If the string contains both single and double quotes → %q() wrapper
|
|
6
|
+
* - If the string contains only single quotes → double-quoted with escaping
|
|
7
|
+
* - Otherwise → single-quoted with escaping
|
|
8
|
+
*
|
|
9
|
+
* Ported from ts-inspec-objects escapeQuotes(), cross-referenced with
|
|
10
|
+
* inspec-parser's RubyRebuilder.
|
|
11
|
+
*/
|
|
12
|
+
export function escapeQuotes(s) {
|
|
13
|
+
const hasSingle = s.includes("'");
|
|
14
|
+
const hasDouble = s.includes('"');
|
|
15
|
+
if (hasSingle && hasDouble) {
|
|
16
|
+
// %q() — escape backslashes before ) so Ruby doesn't treat \) as escaped delimiter
|
|
17
|
+
return `%q(${s.replace(/\\\)/g, '\\\\)')})`;
|
|
18
|
+
}
|
|
19
|
+
if (hasSingle) {
|
|
20
|
+
// Double-quoted: escape backslashes, then double quotes
|
|
21
|
+
return `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
22
|
+
}
|
|
23
|
+
// Single-quoted: escape backslashes, then single quotes
|
|
24
|
+
return `'${s.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ruby-escape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruby-escape.js","sourceRoot":"","sources":["../src/ruby-escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;QAC3B,mFAAmF;QACnF,OAAO,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC;IAC9C,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,wDAAwD;QACxD,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;IAC9D,CAAC;IAED,wDAAwD;IACxD,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AAC9D,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for controlling InSpec profile generation.
|
|
3
|
+
*/
|
|
4
|
+
export interface GeneratorOptions {
|
|
5
|
+
/** Put all controls in a single controls.rb file instead of one file per control. */
|
|
6
|
+
singleFile?: boolean;
|
|
7
|
+
/** Override baseline metadata in the generated inspec.yml. */
|
|
8
|
+
metadata?: ProfileMetadata;
|
|
9
|
+
/** InSpec version constraint for inspec.yml. Default: '~>6.0'. */
|
|
10
|
+
inspecVersion?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Metadata overrides for the generated inspec.yml.
|
|
14
|
+
*/
|
|
15
|
+
export interface ProfileMetadata {
|
|
16
|
+
maintainer?: string;
|
|
17
|
+
copyright?: string;
|
|
18
|
+
license?: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* An in-memory InSpec profile. No file I/O — the CLI is responsible for writing.
|
|
23
|
+
*/
|
|
24
|
+
export interface InSpecProfile {
|
|
25
|
+
/** The inspec.yml content as a YAML string. */
|
|
26
|
+
inspecYml: string;
|
|
27
|
+
/** Map of filename (e.g. 'controls/SV-238196.rb') to Ruby source code. */
|
|
28
|
+
controls: Map<string, string>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qFAAqF;IACrF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mitre/hdf-generators",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Generate InSpec profile stubs from HDF Baseline definitions",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/mitre/hdf-libs.git",
|
|
23
|
+
"directory": "hdf-generators"
|
|
24
|
+
},
|
|
25
|
+
"author": "MITRE Corporation",
|
|
26
|
+
"license": "Apache-2.0",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@mitre/hdf-schema": "2.0.0"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=20.0.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"hdf",
|
|
35
|
+
"heimdall",
|
|
36
|
+
"inspec",
|
|
37
|
+
"generator",
|
|
38
|
+
"profile",
|
|
39
|
+
"stig"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "pnpm clean && tsc",
|
|
43
|
+
"clean": "rimraf dist",
|
|
44
|
+
"test": "pnpm run test:ts",
|
|
45
|
+
"test:ts": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"test:coverage": "vitest run --coverage",
|
|
48
|
+
"type-check": "tsc --noEmit",
|
|
49
|
+
"lint": "eslint src test",
|
|
50
|
+
"lint:fix": "eslint src test --fix"
|
|
51
|
+
}
|
|
52
|
+
}
|