seahaven-org-baseline/lib/hcptf-policy-aspect.ts
Adam Moussa 031e1d1a3b
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
refactor(iam): fold seahaven-site roles into seahaven-hcptf (#175)
Prod HCP exec roles for seahaven-site now live in the same stack as payments-dashboard so role ownership is one stack.
2026-10-02 17:30:52 +00:00

59 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 only. That stack owns payments-dashboard
* in prod and dev, and seahaven-site in prod.
*
* `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");
}
}
}