Assessor_2.0/src/profiles/security-domain-mapping.ts

50 lines
2.4 KiB
TypeScript

/**
* Declarative Security Domain mapping of one scanner profile (user decision 2026-10-04).
*
* A mapping reads only fields that Raw Data shows for a Work record and the scanner's own
* structure: native categories, exact rule IDs, native tags, report section titles, suite
* or control IDs and GPO policy identities. Titles, descriptions and remediation prose are
* never read. The assignment depends on the check only, never on its outcome.
*/
export type SecurityDomainId = 'identity' | 'privilege' | 'infrastructure' | 'hardening' | 'cloud' | 'recovery';
/** 1 native category or rule, 2 report section, 3 suite/control ID, 4 GPO policy identity, 5 source fallback. */
export type SecurityDomainTier = 1 | 2 | 3 | 4 | 5;
export type SecurityDomainMethod =
| 'native-category' | 'native-rule-id' | 'native-tag' | 'native-target'
| 'report-section' | 'suite-control-id' | 'policy-section' | 'registry-key';
export interface SecurityDomainRuleSet {
tier: Exclude<SecurityDomainTier, 5>;
method: SecurityDomainMethod;
/** Raw Data field label, compared case-insensitively; alternatives name the same native field in other report formats. */
field: string | ReadonlyArray<string>;
/**
* `exact`: the whole value equals a key. `prefix`: the longest key the value starts with
* (with `boundary`, only at that separator). `list-item`: one item of a comma/semicolon list
* equals a key; the first entry in declaration order wins. `section-path`: a ` > ` separated
* title path; every key segment must start the value segment at the same depth, and the
* longest matching key path wins.
*/
match: 'exact' | 'prefix' | 'list-item' | 'section-path';
boundary?: string;
/** Applies the rule set only when another Raw Data field has exactly this value. */
when?: { field: string; equals: string };
entries: ReadonlyArray<readonly [string, SecurityDomainId]>;
}
export interface SecurityDomainMapping {
version: string;
profileId: string;
/** Tool names as Raw Data shows them in `Source: Scan` before ` · `, and canonical tool IDs. */
toolNames: ReadonlyArray<string>;
ruleSets: ReadonlyArray<SecurityDomainRuleSet>;
/** Tier 5: the area the source checks as a whole, optionally refined by an exact field value. */
fallback: {
domain: SecurityDomainId;
reason: string;
byField?: { field: string; entries: ReadonlyArray<readonly [string, SecurityDomainId]> };
};
}