@intentius/chant-lexicon-aws 0.41.19 → 0.41.20

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.
@@ -1,3 +1,5 @@
1
+ export { OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail } from "./landing-zone.js";
2
+ export type { OrganizationRootProps, GovernanceFoundationProps, RegionRestrictionProps, OrganizationTrailProps, } from "./landing-zone.js";
1
3
  export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda } from "./lambda-function.js";
2
4
  export type { LambdaFunctionProps } from "./lambda-function.js";
3
5
  export { LambdaApi } from "./lambda-api.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACvG,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,WAAW,IAAI,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACzE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,IAAI,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACxH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Landing-zone bootstrap composites (#791, epic #787 C1).
3
+ *
4
+ * Fixed-shape resources for greenfield creation of the recommended
5
+ * governance foundation through a management-account stack. The evaluability
6
+ * rules (EVL002/004) require composites to declare a fixed set of resources,
7
+ * so these carry the foundation only; arbitrary OU/account trees are
8
+ * authored as config with `landingZoneConfig()` (../governance.ts) and
9
+ * reconciled by the AWS cloud warden (#792), and further OUs/accounts are
10
+ * declared as ordinary resources referencing these members' ids.
11
+ *
12
+ * The pieces compose:
13
+ * const org = OrganizationRoot({}); // greenfield only
14
+ * const lz = GovernanceFoundation({ parentRootId: org.organization.RootId });
15
+ * const rr = RegionRestriction({ regions: ["eu-west-1"], targetIds: [org.organization.RootId] });
16
+ * const at = OrganizationTrail({ bucket: "acme-org-audit" });
17
+ * Brownfield skips OrganizationRoot and passes the existing root id
18
+ * ("r-...") to GovernanceFoundation.
19
+ */
20
+ import { Organization, OrganizationalUnit, OrganizationsPolicy, Trail } from "../generated/index.js";
21
+ export interface OrganizationRootProps {
22
+ featureSet?: "ALL" | "CONSOLIDATED_BILLING";
23
+ }
24
+ export type OrganizationRootResult = {
25
+ organization: InstanceType<typeof Organization>;
26
+ };
27
+ /** Creates the organization itself. Control Tower / existing orgs skip this. */
28
+ export declare const OrganizationRoot: import("@intentius/chant").CompositeDefinition<OrganizationRootProps, OrganizationRootResult>;
29
+ export interface GovernanceFoundationProps {
30
+ /** The organization root to hang the foundation off ("r-..." or `OrganizationRoot(...).organization.RootId`). */
31
+ parentRootId: string;
32
+ }
33
+ export type GovernanceFoundationResult = {
34
+ ouSecurity: InstanceType<typeof OrganizationalUnit>;
35
+ ouInfrastructure: InstanceType<typeof OrganizationalUnit>;
36
+ ouSandbox: InstanceType<typeof OrganizationalUnit>;
37
+ ouWorkloads: InstanceType<typeof OrganizationalUnit>;
38
+ scpDenyLeaveOrganization: InstanceType<typeof OrganizationsPolicy>;
39
+ scpDenyAuditTamper: InstanceType<typeof OrganizationsPolicy>;
40
+ };
41
+ /**
42
+ * Security / Infrastructure / Sandbox / Workloads OUs,
43
+ * `deny-leave-organization` attached at the root and `deny-audit-tamper`
44
+ * on the Security OU — the same baseline `landingZoneConfig()` declares.
45
+ */
46
+ export declare const GovernanceFoundation: import("@intentius/chant").CompositeDefinition<GovernanceFoundationProps, GovernanceFoundationResult>;
47
+ export interface RegionRestrictionProps {
48
+ /** The only regions requests may target (global services excepted). */
49
+ regions: string[];
50
+ /** Root/OU ids the SCP attaches to. */
51
+ targetIds: string[];
52
+ }
53
+ export type RegionRestrictionResult = {
54
+ scpRegionRestriction: InstanceType<typeof OrganizationsPolicy>;
55
+ };
56
+ export declare const RegionRestriction: import("@intentius/chant").CompositeDefinition<RegionRestrictionProps, RegionRestrictionResult>;
57
+ export interface OrganizationTrailProps {
58
+ /** S3 bucket the organization trail delivers into. */
59
+ bucket: string;
60
+ }
61
+ export type OrganizationTrailResult = {
62
+ trail: InstanceType<typeof Trail>;
63
+ };
64
+ export declare const OrganizationTrail: import("@intentius/chant").CompositeDefinition<OrganizationTrailProps, OrganizationTrailResult>;
65
+ //# sourceMappingURL=landing-zone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"landing-zone.d.ts","sourceRoot":"","sources":["../../src/composites/landing-zone.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,EACN,MAAM,cAAc,CAAC;AAOtB,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,KAAK,GAAG,sBAAsB,CAAC;CAC7C;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,+FAGP,CAAC;AAMvB,MAAM,WAAW,yBAAyB;IACxC,iHAAiH;IACjH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACpD,gBAAgB,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAC1D,SAAS,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACnD,WAAW,EAAE,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAC;IACrD,wBAAwB,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;IACnE,kBAAkB,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;CAC9D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,uGA6BP,CAAC;AAM3B,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uCAAuC;IACvC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,oBAAoB,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,iBAAiB,iGAUP,CAAC;AAMxB,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,YAAY,CAAC,OAAO,KAAK,CAAC,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,iGAQP,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * AWS governance authoring (#791, epic #787 C1): the desired-state config
3
+ * shape the AWS cloud warden (#792) reconciles, and `landingZoneConfig()` —
4
+ * the typed authoring layer that emits it.
5
+ *
6
+ * This is deliberately NOT a composite. The evaluability rules (EVL002/004,
7
+ * #916/#952) require composites to declare a fixed set of resources, so a
8
+ * data-driven OU tree walker cannot be one. The split mirrors the SCM
9
+ * wardens: authoring emits config (this module, arbitrary cardinality);
10
+ * resources for greenfield bootstrap are the fixed-shape composites in
11
+ * `composites/landing-zone.ts`; the warden consumes only the config.
12
+ *
13
+ * GCP (Folder/OrgPolicy/AuditConfig) and Azure (blocked on #1545)
14
+ * counterparts are tracked as #791 follow-ups.
15
+ */
16
+ /** An SCP definition, keyed by name in `AwsGovernanceConfig.scps`. */
17
+ export interface ScpConfig {
18
+ description?: string;
19
+ /** The policy document (SCP JSON). */
20
+ document: Record<string, unknown>;
21
+ }
22
+ /** A member account declared inside an OU. */
23
+ export interface AccountConfig {
24
+ name: string;
25
+ email: string;
26
+ }
27
+ /** One OU: its guardrails, accounts, and child OUs, keyed by OU name. */
28
+ export interface OuConfig {
29
+ /** Names of SCPs (from `scps`) attached to this OU. */
30
+ scps?: string[];
31
+ accounts?: AccountConfig[];
32
+ children?: Record<string, OuConfig>;
33
+ }
34
+ /**
35
+ * The desired-state governance tree for one AWS organization. This is the
36
+ * shape `wardens/aws` (#792) loads as config — the AWS counterpart of the
37
+ * SCM wardens' GovernanceConfig. Cycles map onto the governance verbs
38
+ * (#790): the OU/account tree is `org-unit`, SCPs are `policy-guardrail`,
39
+ * audit sinks are `audit-sink`.
40
+ */
41
+ export interface AwsGovernanceConfig {
42
+ organization: {
43
+ /** SCP names attached at the organization root. */
44
+ scps?: string[];
45
+ };
46
+ /** Top-level OUs under the root, keyed by OU name. */
47
+ ous: Record<string, OuConfig>;
48
+ /** SCP definitions, keyed by the names the tree attaches. */
49
+ scps: Record<string, ScpConfig>;
50
+ /** Where audit evidence flows. */
51
+ auditSinks?: {
52
+ cloudtrail?: {
53
+ bucket: string;
54
+ multiRegion: boolean;
55
+ };
56
+ };
57
+ }
58
+ export declare const DENY_LEAVE_ORGANIZATION: ScpConfig;
59
+ export declare const DENY_AUDIT_TAMPER: ScpConfig;
60
+ /** Deny requests outside `regions`, excepting global services. */
61
+ export declare function regionRestriction(regions: readonly string[]): ScpConfig;
62
+ /**
63
+ * The recommended foundation OU structure. Exported so callers can extend it
64
+ * rather than restate it.
65
+ */
66
+ export declare const FOUNDATION_OUS: Record<string, OuConfig>;
67
+ export interface LandingZoneConfigProps {
68
+ /**
69
+ * Start from the recommended foundation: Security / Infrastructure /
70
+ * Sandbox / Workloads OUs, `deny-leave-organization` at the root, and
71
+ * `deny-audit-tamper` on Security. Default true; your `ous`/`scps` merge
72
+ * over it (same-name keys win).
73
+ */
74
+ foundation?: boolean;
75
+ /** Adds a region-restriction SCP at the root allowing only these regions. */
76
+ allowedRegions?: string[];
77
+ /** OU tree, merged over the foundation's. Greenfield (full tree) and brownfield (partial subtree) are both just this map. */
78
+ ous?: Record<string, OuConfig>;
79
+ /** SCP definitions, merged over the foundation's. */
80
+ scps?: Record<string, ScpConfig>;
81
+ /** Extra SCP names to attach at the organization root. */
82
+ rootScps?: string[];
83
+ /** Declare an organization CloudTrail flowing into this bucket. */
84
+ cloudtrailBucket?: string;
85
+ }
86
+ /**
87
+ * Author the desired-state tree the AWS cloud warden (#792) reconciles.
88
+ * Pure. Throws when the tree attaches an SCP name with no definition; only
89
+ * SCPs the tree actually attaches are included in the output.
90
+ */
91
+ export declare function landingZoneConfig(props?: LandingZoneConfigProps): AwsGovernanceConfig;
92
+ //# sourceMappingURL=governance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance.d.ts","sourceRoot":"","sources":["../src/governance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,sEAAsE;AACtE,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,yEAAyE;AACzE,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE;QACZ,mDAAmD;QACnD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IACF,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,kCAAkC;IAClC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,OAAO,CAAA;SAAE,CAAC;KACvD,CAAC;CACH;AAMD,eAAO,MAAM,uBAAuB,EAAE,SAMrC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,SAkB/B,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAuBvE;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAKnD,CAAC;AAMF,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,6HAA6H;IAC7H,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,sBAA2B,GAAG,mBAAmB,CAoCzF"}
package/dist/index.d.ts CHANGED
@@ -23,10 +23,12 @@ export type { CFNSchema, SchemaProperty, SchemaDefinition } from "./spec/fetch.j
23
23
  export { parseCFNSchema, cfnShortName, cfnServiceName } from "./spec/parse.js";
24
24
  export type { SchemaParseResult, ParsedResource, ParsedProperty, ParsedAttribute, ParsedPropertyType, ParsedEnum, PropertyConstraints } from "./spec/parse.js";
25
25
  export { S3Actions, LambdaActions, DynamoDBActions, SQSActions, SNSActions, IAMActions, ECRActions, LogsActions, ECSActions } from "./actions/index.js";
26
- export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda, LambdaApi, LambdaScheduled, ScheduledLambda, LambdaSqs, LambdaEventBridge, LambdaDynamoDB, LambdaS3, LambdaSns, VpcDefault, FargateAlb, AlbShared, FargateService, RdsInstance, RdsPostgres, EfsWithAccessPoint, Ec2InstanceRole, MinimalVpc, EksCluster, SolrFargateService, MicrovmApp, MICROVM_LIMITS, AgentCoreAgent, } from "./composites/index.js";
27
- export type { LambdaFunctionProps, LambdaApiProps, ScheduledLambdaProps, LambdaSqsProps, LambdaEventBridgeProps, LambdaDynamoDBProps, LambdaS3Props, LambdaSnsProps, VpcDefaultProps, FargateAlbProps, AlbSharedProps, FargateServiceProps, RdsInstanceProps, RdsPostgresProps, EfsWithAccessPointProps, Ec2InstanceRoleProps, MinimalVpcProps, EksClusterProps, SolrFargateServiceProps, MicrovmAppProps, MicrovmAppResult, MicrovmAppBuildConnectorProps, MicrovmMemoryMiB, AgentCoreAgentProps, AgentCoreAgentResult, } from "./composites/index.js";
26
+ export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda, LambdaApi, LambdaScheduled, ScheduledLambda, LambdaSqs, LambdaEventBridge, LambdaDynamoDB, LambdaS3, LambdaSns, VpcDefault, FargateAlb, AlbShared, FargateService, RdsInstance, RdsPostgres, EfsWithAccessPoint, Ec2InstanceRole, MinimalVpc, EksCluster, SolrFargateService, MicrovmApp, MICROVM_LIMITS, AgentCoreAgent, OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail, } from "./composites/index.js";
27
+ export type { LambdaFunctionProps, LambdaApiProps, ScheduledLambdaProps, LambdaSqsProps, LambdaEventBridgeProps, LambdaDynamoDBProps, LambdaS3Props, LambdaSnsProps, VpcDefaultProps, FargateAlbProps, AlbSharedProps, FargateServiceProps, RdsInstanceProps, RdsPostgresProps, EfsWithAccessPointProps, Ec2InstanceRoleProps, MinimalVpcProps, EksClusterProps, SolrFargateServiceProps, MicrovmAppProps, MicrovmAppResult, MicrovmAppBuildConnectorProps, MicrovmMemoryMiB, AgentCoreAgentProps, AgentCoreAgentResult, OrganizationRootProps, GovernanceFoundationProps, RegionRestrictionProps, OrganizationTrailProps, } from "./composites/index.js";
28
28
  export { generate, writeGeneratedFiles } from "./codegen/generate.js";
29
29
  export { packageLexicon } from "./codegen/package.js";
30
30
  export type { PackageOptions, PackageResult } from "./codegen/package.js";
31
31
  export { awsCapabilityPlugin } from "./components/capability-plugin.js";
32
+ export { landingZoneConfig, regionRestriction, DENY_AUDIT_TAMPER, DENY_LEAVE_ORGANIZATION, FOUNDATION_OUS } from "./governance.js";
33
+ export type { AwsGovernanceConfig, LandingZoneConfigProps, OuConfig, ScpConfig, AccountConfig } from "./governance.js";
32
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "cebe01c742c2844aca5fd34dce088449c87d661d96ee72dd4ed6c02ca3c4acb1",
4
+ "manifest.json": "34e5cc07ea3f4ee6dc9f368d1439bbc43e8c5ef6a012ec0f7d03ce53816e08f6",
5
5
  "meta.json": "2e4cae67cbc2eb2962c3dd0aa57008ae96fb725dd0118af7b04b2b44eab7722a",
6
6
  "types/index.d.ts": "6d6b37bd14a9b40fb3ff5c66e1cb49be1ae1032de47a4e167cf5f411c943b7f5",
7
7
  "rules/hardcoded-region.ts": "5a0eaf7ab391231fe6cd51426ece29539cb4b36f31c8dd060956638fed55722a",
@@ -59,5 +59,5 @@
59
59
  "skills/chant-aws-eks.md": "8789255709ff004ad0a875fd5999edcdc66fc6e33d710db058d9f42703bcfdfe",
60
60
  "skills/chant-aws-carve-terraform.md": "f4c6fe1c702250665f90d82b3bdaba5ea50ae75e380a8ae321dad6eb1c39683e"
61
61
  },
62
- "composite": "325693aace617ceb31be814498702a442870b3af1aa42dc40eb965e49243893c"
62
+ "composite": "e0f1e5822bf0c7d39fa16c05f7e259344432b4eb815d7cc005714857a8d833b6"
63
63
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws",
3
- "version": "0.41.19",
3
+ "version": "0.41.20",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "AWS",
6
6
  "intrinsics": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-aws",
3
- "version": "0.41.19",
3
+ "version": "0.41.20",
4
4
  "description": "AWS CloudFormation lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -80,7 +80,7 @@
80
80
  "typescript": "^5.9.3"
81
81
  },
82
82
  "peerDependencies": {
83
- "@intentius/chant": "^0.41.19",
83
+ "@intentius/chant": "^0.41.20",
84
84
  "typescript": "^5.9.3"
85
85
  }
86
86
  }
@@ -1,3 +1,10 @@
1
+ export { OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail } from "./landing-zone";
2
+ export type {
3
+ OrganizationRootProps,
4
+ GovernanceFoundationProps,
5
+ RegionRestrictionProps,
6
+ OrganizationTrailProps,
7
+ } from "./landing-zone";
1
8
  export { LambdaFunction, LambdaNode, LambdaPython, NodeLambda, PythonLambda } from "./lambda-function";
2
9
  export type { LambdaFunctionProps } from "./lambda-function";
3
10
  export { LambdaApi } from "./lambda-api";
@@ -0,0 +1,53 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { expandComposite } from "@intentius/chant";
3
+ import { AttrRef } from "@intentius/chant/attrref";
4
+ import { GovernanceFoundation, OrganizationRoot, OrganizationTrail, RegionRestriction } from "./landing-zone";
5
+
6
+ describe("GovernanceFoundation (#791)", () => {
7
+ test("declares the foundation OUs and baseline SCPs", () => {
8
+ const lz = GovernanceFoundation({ parentRootId: "r-abc1" });
9
+ expect(Object.keys(lz.members)).toEqual([
10
+ "ouSecurity",
11
+ "ouInfrastructure",
12
+ "ouSandbox",
13
+ "ouWorkloads",
14
+ "scpDenyLeaveOrganization",
15
+ "scpDenyAuditTamper",
16
+ ]);
17
+ });
18
+
19
+ test("deny-leave-organization targets the root; deny-audit-tamper targets the Security OU", () => {
20
+ const lz = GovernanceFoundation({ parentRootId: "r-abc1" });
21
+ expect((lz.scpDenyLeaveOrganization as any).props.TargetIds).toEqual(["r-abc1"]);
22
+ const tamperTargets = (lz.scpDenyAuditTamper as any).props.TargetIds;
23
+ expect(tamperTargets).toHaveLength(1);
24
+ expect(tamperTargets[0]).toBeInstanceOf(AttrRef);
25
+ });
26
+
27
+ test("brownfield and greenfield wire the same way", () => {
28
+ const org = OrganizationRoot({});
29
+ const green = GovernanceFoundation({ parentRootId: org.organization.RootId });
30
+ expect((green.ouSecurity as any).props.ParentId).toBeInstanceOf(AttrRef);
31
+ const brown = GovernanceFoundation({ parentRootId: "r-live" });
32
+ expect((brown.ouSecurity as any).props.ParentId).toBe("r-live");
33
+ });
34
+
35
+ test("expandComposite produces prefixed logical names", () => {
36
+ const expanded = expandComposite("lz", GovernanceFoundation({ parentRootId: "r-abc1" }));
37
+ expect([...expanded.keys()]).toContain("lzOuSecurity");
38
+ expect([...expanded.keys()]).toContain("lzScpDenyAuditTamper");
39
+ expect(expanded.size).toBe(6);
40
+ });
41
+
42
+ test("RegionRestriction and OrganizationTrail carry the optional guardrails", () => {
43
+ const rr = RegionRestriction({ regions: ["eu-west-1"], targetIds: ["r-abc1"] });
44
+ const doc = (rr.scpRegionRestriction as any).props.Content;
45
+ expect(JSON.stringify(doc)).toContain("eu-west-1");
46
+ const trail = OrganizationTrail({ bucket: "acme-audit" });
47
+ expect((trail.trail as any).props).toMatchObject({
48
+ S3BucketName: "acme-audit",
49
+ IsOrganizationTrail: true,
50
+ IsLogging: true,
51
+ });
52
+ });
53
+ });
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Landing-zone bootstrap composites (#791, epic #787 C1).
3
+ *
4
+ * Fixed-shape resources for greenfield creation of the recommended
5
+ * governance foundation through a management-account stack. The evaluability
6
+ * rules (EVL002/004) require composites to declare a fixed set of resources,
7
+ * so these carry the foundation only; arbitrary OU/account trees are
8
+ * authored as config with `landingZoneConfig()` (../governance.ts) and
9
+ * reconciled by the AWS cloud warden (#792), and further OUs/accounts are
10
+ * declared as ordinary resources referencing these members' ids.
11
+ *
12
+ * The pieces compose:
13
+ * const org = OrganizationRoot({}); // greenfield only
14
+ * const lz = GovernanceFoundation({ parentRootId: org.organization.RootId });
15
+ * const rr = RegionRestriction({ regions: ["eu-west-1"], targetIds: [org.organization.RootId] });
16
+ * const at = OrganizationTrail({ bucket: "acme-org-audit" });
17
+ * Brownfield skips OrganizationRoot and passes the existing root id
18
+ * ("r-...") to GovernanceFoundation.
19
+ */
20
+
21
+ import { Composite } from "@intentius/chant";
22
+ import {
23
+ Organization,
24
+ OrganizationalUnit,
25
+ OrganizationsPolicy,
26
+ Trail,
27
+ } from "../generated";
28
+ import { DENY_AUDIT_TAMPER, DENY_LEAVE_ORGANIZATION, regionRestriction } from "../governance";
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // OrganizationRoot — greenfield only
32
+ // ---------------------------------------------------------------------------
33
+
34
+ export interface OrganizationRootProps {
35
+ featureSet?: "ALL" | "CONSOLIDATED_BILLING";
36
+ }
37
+
38
+ export type OrganizationRootResult = {
39
+ organization: InstanceType<typeof Organization>;
40
+ };
41
+
42
+ /** Creates the organization itself. Control Tower / existing orgs skip this. */
43
+ export const OrganizationRoot = Composite<OrganizationRootProps, OrganizationRootResult>((props) => {
44
+ const organization = new Organization({ FeatureSet: props.featureSet ?? "ALL" });
45
+ return { organization };
46
+ }, "OrganizationRoot");
47
+
48
+ // ---------------------------------------------------------------------------
49
+ // GovernanceFoundation — the recommended foundation
50
+ // ---------------------------------------------------------------------------
51
+
52
+ export interface GovernanceFoundationProps {
53
+ /** The organization root to hang the foundation off ("r-..." or `OrganizationRoot(...).organization.RootId`). */
54
+ parentRootId: string;
55
+ }
56
+
57
+ export type GovernanceFoundationResult = {
58
+ ouSecurity: InstanceType<typeof OrganizationalUnit>;
59
+ ouInfrastructure: InstanceType<typeof OrganizationalUnit>;
60
+ ouSandbox: InstanceType<typeof OrganizationalUnit>;
61
+ ouWorkloads: InstanceType<typeof OrganizationalUnit>;
62
+ scpDenyLeaveOrganization: InstanceType<typeof OrganizationsPolicy>;
63
+ scpDenyAuditTamper: InstanceType<typeof OrganizationsPolicy>;
64
+ };
65
+
66
+ /**
67
+ * Security / Infrastructure / Sandbox / Workloads OUs,
68
+ * `deny-leave-organization` attached at the root and `deny-audit-tamper`
69
+ * on the Security OU — the same baseline `landingZoneConfig()` declares.
70
+ */
71
+ export const GovernanceFoundation = Composite<GovernanceFoundationProps, GovernanceFoundationResult>((props) => {
72
+ const ouSecurity = new OrganizationalUnit({ Name: "Security", ParentId: props.parentRootId });
73
+ const ouInfrastructure = new OrganizationalUnit({ Name: "Infrastructure", ParentId: props.parentRootId });
74
+ const ouSandbox = new OrganizationalUnit({ Name: "Sandbox", ParentId: props.parentRootId });
75
+ const ouWorkloads = new OrganizationalUnit({ Name: "Workloads", ParentId: props.parentRootId });
76
+
77
+ const scpDenyLeaveOrganization = new OrganizationsPolicy({
78
+ Name: "deny-leave-organization",
79
+ Type: "SERVICE_CONTROL_POLICY",
80
+ Content: DENY_LEAVE_ORGANIZATION.document,
81
+ Description: DENY_LEAVE_ORGANIZATION.description,
82
+ TargetIds: [props.parentRootId],
83
+ });
84
+ const scpDenyAuditTamper = new OrganizationsPolicy({
85
+ Name: "deny-audit-tamper",
86
+ Type: "SERVICE_CONTROL_POLICY",
87
+ Content: DENY_AUDIT_TAMPER.document,
88
+ Description: DENY_AUDIT_TAMPER.description,
89
+ TargetIds: [ouSecurity.Id],
90
+ });
91
+
92
+ return {
93
+ ouSecurity,
94
+ ouInfrastructure,
95
+ ouSandbox,
96
+ ouWorkloads,
97
+ scpDenyLeaveOrganization,
98
+ scpDenyAuditTamper,
99
+ };
100
+ }, "GovernanceFoundation");
101
+
102
+ // ---------------------------------------------------------------------------
103
+ // RegionRestriction — optional root guardrail
104
+ // ---------------------------------------------------------------------------
105
+
106
+ export interface RegionRestrictionProps {
107
+ /** The only regions requests may target (global services excepted). */
108
+ regions: string[];
109
+ /** Root/OU ids the SCP attaches to. */
110
+ targetIds: string[];
111
+ }
112
+
113
+ export type RegionRestrictionResult = {
114
+ scpRegionRestriction: InstanceType<typeof OrganizationsPolicy>;
115
+ };
116
+
117
+ export const RegionRestriction = Composite<RegionRestrictionProps, RegionRestrictionResult>((props) => {
118
+ const policy = regionRestriction(props.regions);
119
+ const scpRegionRestriction = new OrganizationsPolicy({
120
+ Name: "region-restriction",
121
+ Type: "SERVICE_CONTROL_POLICY",
122
+ Content: policy.document,
123
+ Description: policy.description,
124
+ TargetIds: props.targetIds,
125
+ });
126
+ return { scpRegionRestriction };
127
+ }, "RegionRestriction");
128
+
129
+ // ---------------------------------------------------------------------------
130
+ // OrganizationTrail — the audit sink
131
+ // ---------------------------------------------------------------------------
132
+
133
+ export interface OrganizationTrailProps {
134
+ /** S3 bucket the organization trail delivers into. */
135
+ bucket: string;
136
+ }
137
+
138
+ export type OrganizationTrailResult = {
139
+ trail: InstanceType<typeof Trail>;
140
+ };
141
+
142
+ export const OrganizationTrail = Composite<OrganizationTrailProps, OrganizationTrailResult>((props) => {
143
+ const trail = new Trail({
144
+ IsLogging: true,
145
+ S3BucketName: props.bucket,
146
+ IsMultiRegionTrail: true,
147
+ IsOrganizationTrail: true,
148
+ });
149
+ return { trail };
150
+ }, "OrganizationTrail");
@@ -0,0 +1,54 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { landingZoneConfig, FOUNDATION_OUS } from "./governance";
3
+
4
+ describe("landingZoneConfig (#791)", () => {
5
+ test("the default is the recommended foundation", () => {
6
+ const cfg = landingZoneConfig();
7
+ expect(Object.keys(cfg.ous)).toEqual(["Security", "Infrastructure", "Sandbox", "Workloads"]);
8
+ expect(cfg.organization.scps).toEqual(["deny-leave-organization"]);
9
+ expect(cfg.ous.Security.scps).toEqual(["deny-audit-tamper"]);
10
+ expect(Object.keys(cfg.scps).sort()).toEqual(["deny-audit-tamper", "deny-leave-organization"]);
11
+ expect(cfg.auditSinks).toBeUndefined();
12
+ });
13
+
14
+ test("custom OUs and accounts merge over the foundation (brownfield: partial trees work)", () => {
15
+ const cfg = landingZoneConfig({
16
+ ous: {
17
+ Workloads: {
18
+ children: { Prod: { accounts: [{ name: "checkout", email: "aws+checkout@acme.dev" }] } },
19
+ },
20
+ },
21
+ });
22
+ // Same-name key wins over the foundation's Workloads…
23
+ expect(cfg.ous.Workloads.children?.Prod.accounts?.[0].name).toBe("checkout");
24
+ // …while the rest of the foundation persists.
25
+ expect(cfg.ous.Security).toEqual(FOUNDATION_OUS.Security);
26
+
27
+ const partial = landingZoneConfig({ foundation: false, ous: { Legacy: {} }, rootScps: [] });
28
+ expect(Object.keys(partial.ous)).toEqual(["Legacy"]);
29
+ expect(partial.organization.scps).toBeUndefined();
30
+ expect(partial.scps).toEqual({});
31
+ });
32
+
33
+ test("allowedRegions adds a root region-restriction SCP", () => {
34
+ const cfg = landingZoneConfig({ allowedRegions: ["eu-west-1", "eu-central-1"] });
35
+ expect(cfg.organization.scps).toContain("region-restriction");
36
+ expect(JSON.stringify(cfg.scps["region-restriction"].document)).toContain("eu-central-1");
37
+ });
38
+
39
+ test("cloudtrailBucket declares the audit sink", () => {
40
+ const cfg = landingZoneConfig({ cloudtrailBucket: "acme-audit" });
41
+ expect(cfg.auditSinks?.cloudtrail).toEqual({ bucket: "acme-audit", multiRegion: true });
42
+ });
43
+
44
+ test("only attached SCPs are emitted; attaching an undefined SCP throws", () => {
45
+ const cfg = landingZoneConfig({
46
+ scps: { unused: { document: { Version: "2012-10-17", Statement: [] } } },
47
+ });
48
+ expect(cfg.scps.unused).toBeUndefined();
49
+
50
+ expect(() => landingZoneConfig({ ous: { Security: { scps: ["nope"] } } })).toThrowError(
51
+ 'SCP "nope" is attached but not defined',
52
+ );
53
+ });
54
+ });
@@ -0,0 +1,198 @@
1
+ /**
2
+ * AWS governance authoring (#791, epic #787 C1): the desired-state config
3
+ * shape the AWS cloud warden (#792) reconciles, and `landingZoneConfig()` —
4
+ * the typed authoring layer that emits it.
5
+ *
6
+ * This is deliberately NOT a composite. The evaluability rules (EVL002/004,
7
+ * #916/#952) require composites to declare a fixed set of resources, so a
8
+ * data-driven OU tree walker cannot be one. The split mirrors the SCM
9
+ * wardens: authoring emits config (this module, arbitrary cardinality);
10
+ * resources for greenfield bootstrap are the fixed-shape composites in
11
+ * `composites/landing-zone.ts`; the warden consumes only the config.
12
+ *
13
+ * GCP (Folder/OrgPolicy/AuditConfig) and Azure (blocked on #1545)
14
+ * counterparts are tracked as #791 follow-ups.
15
+ */
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // The desired-state config shape the AWS cloud warden consumes (#792)
19
+ // ---------------------------------------------------------------------------
20
+
21
+ /** An SCP definition, keyed by name in `AwsGovernanceConfig.scps`. */
22
+ export interface ScpConfig {
23
+ description?: string;
24
+ /** The policy document (SCP JSON). */
25
+ document: Record<string, unknown>;
26
+ }
27
+
28
+ /** A member account declared inside an OU. */
29
+ export interface AccountConfig {
30
+ name: string;
31
+ email: string;
32
+ }
33
+
34
+ /** One OU: its guardrails, accounts, and child OUs, keyed by OU name. */
35
+ export interface OuConfig {
36
+ /** Names of SCPs (from `scps`) attached to this OU. */
37
+ scps?: string[];
38
+ accounts?: AccountConfig[];
39
+ children?: Record<string, OuConfig>;
40
+ }
41
+
42
+ /**
43
+ * The desired-state governance tree for one AWS organization. This is the
44
+ * shape `wardens/aws` (#792) loads as config — the AWS counterpart of the
45
+ * SCM wardens' GovernanceConfig. Cycles map onto the governance verbs
46
+ * (#790): the OU/account tree is `org-unit`, SCPs are `policy-guardrail`,
47
+ * audit sinks are `audit-sink`.
48
+ */
49
+ export interface AwsGovernanceConfig {
50
+ organization: {
51
+ /** SCP names attached at the organization root. */
52
+ scps?: string[];
53
+ };
54
+ /** Top-level OUs under the root, keyed by OU name. */
55
+ ous: Record<string, OuConfig>;
56
+ /** SCP definitions, keyed by the names the tree attaches. */
57
+ scps: Record<string, ScpConfig>;
58
+ /** Where audit evidence flows. */
59
+ auditSinks?: {
60
+ cloudtrail?: { bucket: string; multiRegion: boolean };
61
+ };
62
+ }
63
+
64
+ // ---------------------------------------------------------------------------
65
+ // Baseline guardrails (shared with the bootstrap composites)
66
+ // ---------------------------------------------------------------------------
67
+
68
+ export const DENY_LEAVE_ORGANIZATION: ScpConfig = {
69
+ description: "Member accounts may not remove themselves from the organization.",
70
+ document: {
71
+ Version: "2012-10-17",
72
+ Statement: [{ Effect: "Deny", Action: "organizations:LeaveOrganization", Resource: "*" }],
73
+ },
74
+ };
75
+
76
+ export const DENY_AUDIT_TAMPER: ScpConfig = {
77
+ description: "Audit trails and recorders cannot be stopped or deleted from member accounts.",
78
+ document: {
79
+ Version: "2012-10-17",
80
+ Statement: [
81
+ {
82
+ Effect: "Deny",
83
+ Action: [
84
+ "cloudtrail:StopLogging",
85
+ "cloudtrail:DeleteTrail",
86
+ "config:StopConfigurationRecorder",
87
+ "config:DeleteConfigurationRecorder",
88
+ "config:DeleteDeliveryChannel",
89
+ ],
90
+ Resource: "*",
91
+ },
92
+ ],
93
+ },
94
+ };
95
+
96
+ /** Deny requests outside `regions`, excepting global services. */
97
+ export function regionRestriction(regions: readonly string[]): ScpConfig {
98
+ return {
99
+ description: `Deny requests outside [${regions.join(", ")}] except global services.`,
100
+ document: {
101
+ Version: "2012-10-17",
102
+ Statement: [
103
+ {
104
+ Effect: "Deny",
105
+ NotAction: [
106
+ "iam:*",
107
+ "organizations:*",
108
+ "route53:*",
109
+ "cloudfront:*",
110
+ "sts:*",
111
+ "support:*",
112
+ "budgets:*",
113
+ ],
114
+ Resource: "*",
115
+ Condition: { StringNotEquals: { "aws:RequestedRegion": regions } },
116
+ },
117
+ ],
118
+ },
119
+ };
120
+ }
121
+
122
+ /**
123
+ * The recommended foundation OU structure. Exported so callers can extend it
124
+ * rather than restate it.
125
+ */
126
+ export const FOUNDATION_OUS: Record<string, OuConfig> = {
127
+ Security: { scps: ["deny-audit-tamper"] },
128
+ Infrastructure: {},
129
+ Sandbox: {},
130
+ Workloads: {},
131
+ };
132
+
133
+ // ---------------------------------------------------------------------------
134
+ // Authoring
135
+ // ---------------------------------------------------------------------------
136
+
137
+ export interface LandingZoneConfigProps {
138
+ /**
139
+ * Start from the recommended foundation: Security / Infrastructure /
140
+ * Sandbox / Workloads OUs, `deny-leave-organization` at the root, and
141
+ * `deny-audit-tamper` on Security. Default true; your `ous`/`scps` merge
142
+ * over it (same-name keys win).
143
+ */
144
+ foundation?: boolean;
145
+ /** Adds a region-restriction SCP at the root allowing only these regions. */
146
+ allowedRegions?: string[];
147
+ /** OU tree, merged over the foundation's. Greenfield (full tree) and brownfield (partial subtree) are both just this map. */
148
+ ous?: Record<string, OuConfig>;
149
+ /** SCP definitions, merged over the foundation's. */
150
+ scps?: Record<string, ScpConfig>;
151
+ /** Extra SCP names to attach at the organization root. */
152
+ rootScps?: string[];
153
+ /** Declare an organization CloudTrail flowing into this bucket. */
154
+ cloudtrailBucket?: string;
155
+ }
156
+
157
+ /**
158
+ * Author the desired-state tree the AWS cloud warden (#792) reconciles.
159
+ * Pure. Throws when the tree attaches an SCP name with no definition; only
160
+ * SCPs the tree actually attaches are included in the output.
161
+ */
162
+ export function landingZoneConfig(props: LandingZoneConfigProps = {}): AwsGovernanceConfig {
163
+ const foundation = props.foundation ?? true;
164
+ const scps: Record<string, ScpConfig> = {
165
+ ...(foundation
166
+ ? { "deny-leave-organization": DENY_LEAVE_ORGANIZATION, "deny-audit-tamper": DENY_AUDIT_TAMPER }
167
+ : {}),
168
+ ...(props.allowedRegions?.length ? { "region-restriction": regionRestriction(props.allowedRegions) } : {}),
169
+ ...props.scps,
170
+ };
171
+ const ous = { ...(foundation ? FOUNDATION_OUS : {}), ...props.ous };
172
+ const rootScps = [
173
+ ...(foundation ? ["deny-leave-organization"] : []),
174
+ ...(props.allowedRegions?.length ? ["region-restriction"] : []),
175
+ ...(props.rootScps ?? []),
176
+ ];
177
+
178
+ const attached = new Set(rootScps);
179
+ const collect = (tree: Record<string, OuConfig>): void => {
180
+ for (const node of Object.values(tree)) {
181
+ for (const s of node.scps ?? []) attached.add(s);
182
+ if (node.children) collect(node.children);
183
+ }
184
+ };
185
+ collect(ous);
186
+ for (const name of attached) {
187
+ if (!scps[name]) throw new Error(`landingZoneConfig: SCP "${name}" is attached but not defined in scps`);
188
+ }
189
+
190
+ return {
191
+ organization: rootScps.length ? { scps: rootScps } : {},
192
+ ous,
193
+ scps: Object.fromEntries(Object.entries(scps).filter(([n]) => attached.has(n))),
194
+ ...(props.cloudtrailBucket
195
+ ? { auditSinks: { cloudtrail: { bucket: props.cloudtrailBucket, multiRegion: true } } }
196
+ : {}),
197
+ };
198
+ }
package/src/index.ts CHANGED
@@ -114,6 +114,7 @@ export {
114
114
  SolrFargateService,
115
115
  MicrovmApp, MICROVM_LIMITS,
116
116
  AgentCoreAgent,
117
+ OrganizationRoot, GovernanceFoundation, RegionRestriction, OrganizationTrail,
117
118
  } from "./composites/index";
118
119
  export type {
119
120
  LambdaFunctionProps, LambdaApiProps, ScheduledLambdaProps,
@@ -124,6 +125,7 @@ export type {
124
125
  SolrFargateServiceProps,
125
126
  MicrovmAppProps, MicrovmAppResult, MicrovmAppBuildConnectorProps, MicrovmMemoryMiB,
126
127
  AgentCoreAgentProps, AgentCoreAgentResult,
128
+ OrganizationRootProps, GovernanceFoundationProps, RegionRestrictionProps, OrganizationTrailProps,
127
129
  } from "./composites/index";
128
130
 
129
131
  // Code generation pipeline
@@ -135,3 +137,8 @@ export type { PackageOptions, PackageResult } from "./codegen/package";
135
137
  // emr-*, code-deploy, …) contributed to core's capability-plugin seam. Core
136
138
  // loads `awsCapabilityPlugin` when a project's chant.config lists this lexicon.
137
139
  export { awsCapabilityPlugin } from "./components/capability-plugin";
140
+
141
+ // AWS governance authoring (#791): the desired-state config the AWS cloud
142
+ // warden (#792) reconciles, and the typed landing-zone authoring layer.
143
+ export { landingZoneConfig, regionRestriction, DENY_AUDIT_TAMPER, DENY_LEAVE_ORGANIZATION, FOUNDATION_OUS } from "./governance";
144
+ export type { AwsGovernanceConfig, LandingZoneConfigProps, OuConfig, ScpConfig, AccountConfig } from "./governance";