@fjall/components-infrastructure 3.8.0 → 3.9.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.
@@ -155,7 +155,10 @@ export class IdentityCenter extends NestedStack {
155
155
  continue;
156
156
  }
157
157
  if (this.managementAccountId === undefined) {
158
- throw new Error(`permissionSets["${name}"] sets includeManagementAccount but no managementAccountId was provided to IdentityCenter`);
158
+ const builtInHint = spec.isDefault
159
+ ? " (a built-in default — pass managementAccountId, or suppress the defaults with defaultPermissionSets: false)"
160
+ : "";
161
+ throw new Error(`permissionSets["${name}"] sets includeManagementAccount but no managementAccountId was provided to IdentityCenter${builtInHint}`);
159
162
  }
160
163
  targets.push([accountName, this.managementAccountId]);
161
164
  }
@@ -74,7 +74,7 @@ interface IdentityCentreBase {
74
74
  * Default 1.
75
75
  */
76
76
  resolutionVersion?: number;
77
- /** false suppresses the three built-in permission sets. Default true. */
77
+ /** false suppresses the built-in permission sets (DEFAULT_PERMISSION_SETS). Default true. */
78
78
  defaultPermissionSets?: boolean;
79
79
  }
80
80
  export type IdentityCentreConfig = (IdentityCentreBase & {
@@ -90,6 +90,12 @@ export type IdentityCentreConfig = (IdentityCentreBase & {
90
90
  export interface DefaultPermissionSetDefinition {
91
91
  managedPolicyArn: string;
92
92
  description: string;
93
+ /** Workload-account scoping for the default. Omitted = every workload account. */
94
+ accounts?: string[];
95
+ /** Management-account opt-in for the default. Default false. */
96
+ includeManagementAccount?: boolean;
97
+ /** ISO-8601 session duration for the default. Omitted = AWS default (PT1H). */
98
+ sessionDuration?: string;
93
99
  }
94
100
  export declare const DEFAULT_PERMISSION_SETS: Record<DefaultPermissionSetName, DefaultPermissionSetDefinition>;
95
101
  export interface ResolvedPermissionSet extends PermissionSetSpec {
@@ -24,6 +24,16 @@ export const DEFAULT_PERMISSION_SETS = {
24
24
  Billing: {
25
25
  managedPolicyArn: "arn:aws:iam::aws:policy/AWSBillingReadOnlyAccess",
26
26
  description: "Permission set for associated Billing policy"
27
+ },
28
+ // Deliberately management-only (never a rider on AdministratorAccess) and
29
+ // memberless by default — grants nothing until someone joins the implicit
30
+ // ManagementAccountAccess group.
31
+ ManagementAccountAccess: {
32
+ managedPolicyArn: "arn:aws:iam::aws:policy/AdministratorAccess",
33
+ description: "Break-glass administrative access to the management account only",
34
+ accounts: [],
35
+ includeManagementAccount: true,
36
+ sessionDuration: "PT2H"
27
37
  }
28
38
  };
29
39
  /**
@@ -38,6 +48,13 @@ export function effectivePermissionSets(config) {
38
48
  result[name] = {
39
49
  managedPolicies: [def.managedPolicyArn],
40
50
  description: def.description,
51
+ ...(def.accounts !== undefined && { accounts: def.accounts }),
52
+ ...(def.includeManagementAccount !== undefined && {
53
+ includeManagementAccount: def.includeManagementAccount
54
+ }),
55
+ ...(def.sessionDuration !== undefined && {
56
+ sessionDuration: def.sessionDuration
57
+ }),
41
58
  isDefault: true
42
59
  };
43
60
  }
@@ -16,8 +16,9 @@ export interface OrganisationProps extends AccountProps {
16
16
  /**
17
17
  * Identity Centre configuration: groups, permission sets, memberships and
18
18
  * (source permitting) users, all declared in code. `false` disables the
19
- * Identity Centre entirely; omitted = the three built-in permission sets
20
- * with no members (inert defaults).
19
+ * Identity Centre entirely; omitted = the built-in permission sets with no
20
+ * members (inert defaults, including the management-only break-glass set
21
+ * ManagementAccountAccess).
21
22
  */
22
23
  identityCentre?: IdentityCentreConfig | false;
23
24
  allowedRegions?: string[];
@@ -13,6 +13,14 @@ export interface SNSTopicProps {
13
13
  * only for a topic that must survive stack deletion.
14
14
  */
15
15
  removalPolicy?: RemovalPolicyString;
16
+ /**
17
+ * SNS message signature version. Defaults to "2" (SHA-256) — the AWS
18
+ * account-level default is "1" (SHA-1, deprecated), which signature-verifying
19
+ * HTTPS consumers (including the Fjall webapp alarm ingest) reject, leaving
20
+ * their subscriptions stuck in PendingConfirmation. Pass "1" only for a
21
+ * legacy consumer that cannot verify SHA-256.
22
+ */
23
+ signatureVersion?: "1" | "2";
16
24
  }
17
25
  export declare class SNSTopic extends Construct {
18
26
  readonly id: string;
@@ -20,7 +20,8 @@ export class SNSTopic extends Construct {
20
20
  fifo: isFifo,
21
21
  contentBasedDeduplication: isFifo
22
22
  ? (props.contentBasedDeduplication ?? true)
23
- : undefined
23
+ : undefined,
24
+ signatureVersion: props.signatureVersion ?? "2"
24
25
  });
25
26
  // An SNS topic is a transient fan-out medium: it holds no durable state
26
27
  // (subscriptions are re-created by the next deploy), so the wrapper defaults
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/components-infrastructure",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "type": "module",
6
6
  "bin": {
@@ -67,8 +67,8 @@
67
67
  },
68
68
  "dependencies": {
69
69
  "@aws-sdk/client-organizations": "^3.1038.0",
70
- "@fjall/generator": "^3.8.0",
71
- "@fjall/util": "^3.8.0",
70
+ "@fjall/generator": "^3.9.0",
71
+ "@fjall/util": "^3.9.0",
72
72
  "constructs": "^10.6.0"
73
73
  },
74
74
  "overrides": {
@@ -82,5 +82,5 @@
82
82
  "engines": {
83
83
  "node": ">=18.0.0"
84
84
  },
85
- "gitHead": "9a137b6bd380f432f6c6e8e43b7932dec0b64a13"
85
+ "gitHead": "7cef1c5c3c09bb333888e65ede3d92b2d88c3c63"
86
86
  }