seahaven-org-baseline/lib/hcptf-policy-aspect.ts
Adam Moussa c6de4e0c7f
Some checks are pending
Deploy / deploy-management (push) Waiting to run
Deploy / deploy-external-dev (push) Waiting to run
Deploy / deploy-security (push) Waiting to run
Deploy / deploy-dev (push) Waiting to run
Deploy / deploy-prod (push) Waiting to run
feat(iam): add seahaven-hcptf and managed site policies (PLAT-79) (#174)
Add seahaven-hcptf in prod and dev for the imported payments-dashboard HCP roles and Lambda boundary, and move seahaven-site-hcptf inline policies to managed policies.
2026-10-01 21:22:44 -04:00

58 lines
2.1 KiB
TypeScript

import * as cdk from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";
import { IConstruct } from "constructs";
/** IAM managed-policy quota, whitespace excluded. */
const MAX_POLICY_CHARS = 6144;
/**
* Fails synth when an HCP stack's managed policy document reaches the IAM
* size quota, or when a role in that stack carries an inline policy.
* Register it on seahaven-hcptf and seahaven-site-hcptf only.
*
* `allowInlinePolicies` is only for the one-time `cdk import` template.
* That template has to name the live inline policies so the following
* deploy can delete them. The default template still rejects inline policies.
*/
export class HcptfPolicyAspect implements cdk.IAspect {
constructor(private readonly allowInlinePolicies = false) {}
public visit(node: IConstruct): void {
if (node instanceof iam.CfnManagedPolicy) {
const size = JSON.stringify(node.policyDocument).replace(/\s/g, "").length;
if (size >= MAX_POLICY_CHARS) {
cdk.Annotations.of(node).addError(
`managed policy document is ${size} characters, whitespace excluded (limit ${MAX_POLICY_CHARS})`,
);
}
}
if (node instanceof iam.CfnRole) {
const policies = node.policies;
if (Array.isArray(policies)) {
for (const policy of policies) {
if (cdk.Token.isUnresolved(policy) || !("policyDocument" in policy)) {
continue;
}
const size = JSON.stringify(policy.policyDocument)
.replace(/\s/g, "")
.length;
if (size >= MAX_POLICY_CHARS) {
cdk.Annotations.of(node).addError(
`inline policy document is ${size} characters, whitespace excluded (limit ${MAX_POLICY_CHARS})`,
);
}
}
if (!this.allowInlinePolicies && policies.length > 0) {
cdk.Annotations.of(node).addError(
"inline policy is not allowed on this role",
);
}
}
}
if (node instanceof iam.CfnPolicy) {
cdk.Annotations.of(node).addError("inline policy is not allowed in this stack");
}
}
}