@k9securityio/k9-cdk
Version:
Provision strong AWS security policies easily using the AWS CDK.
114 lines (113 loc) • 5.84 kB
TypeScript
import { ArnPrincipal, Conditions, PolicyStatement } from 'aws-cdk-lib/aws-iam';
export type ArnEqualsTest = 'ArnEquals';
export type ArnLikeTest = 'ArnLike';
export type ArnConditionTest = ArnEqualsTest | ArnLikeTest;
export declare enum AccessCapability {
ADMINISTER_RESOURCE = "administer-resource",
READ_CONFIG = "read-config",
READ_DATA = "read-data",
WRITE_DATA = "write-data",
DELETE_DATA = "delete-data"
}
export declare function getAccessCapabilityFromValue(accessCapabilityStr: string): AccessCapability;
export interface IAccessSpec {
accessCapabilities: Array<AccessCapability> | AccessCapability;
allowPrincipalArns: Array<string>;
test?: ArnConditionTest;
/**
* Optional list of AWS Organization IDs that restrict the principals specified
* in `allowPrincipalArns`. When present, generated Allow statements will include
* a `StringEquals` condition on `aws:PrincipalOrgID` and a DenyUntrustedOrgs statement will
* be generated for the permissions that are restricted by org IDs.
*
* Org IDs restrict which principals are allowed — they do not replace
* `allowPrincipalArns`. If you want to allow an entire org, add `*` to `allowPrincipalArns` and the org ID to
* `restrictToPrincipalOrgIDs`.
*/
restrictToPrincipalOrgIDs?: Array<string>;
}
/**
* `IAWSServiceAccessGenerator` defines an interface that the k9 policy generators use to grant an AWS service
* access to a protected resource.
*/
export interface IAWSServiceAccessGenerator {
/**
* Make an array of PolicyStatement objects that allow an AWS service, e.g. CloudFront, to access to the
* protected AWS resource.
*/
makeAllowStatements(): Array<PolicyStatement>;
/**
* Make a Conditions object that creates an exception for an AWS service in a protected resource's `DenyEveryoneElse`
* statement.
*/
makeConditionsToExceptFromDenyEveryoneElse(): Conditions;
}
/**
* Check whether the provided access specs ensure that at least one principal can both read and administer configuration.
* @param accessSpecsByCapability is a map of access specs keyed by access capability
*
* @return true when at least one principal that can administer and read configuration exists
*/
export declare function canPrincipalsManageResources(accessSpecsByCapability: Map<AccessCapability, IAccessSpec>): boolean;
/**
* Check if any access spec contains a wildcard principal ("*").
*/
export declare function hasWildcardPrincipal(accessSpecs: Array<IAccessSpec>): boolean;
/**
* Validate that access specs have valid principal ARN + org constraint combinations.
* Throws an error for invalid combinations:
* - Empty allowPrincipalArns
* - Wildcard allowPrincipalArns without restrictToPrincipalOrgIDs (public access)
*/
export declare function validateAccessSpecs(accessSpecs: Array<IAccessSpec>): void;
/**
* Converts a string to PascalCase, which is useful for e.g. policy types that don't
* do not support spaces or hyphens in statement ids.
*
* @param input
*/
export declare function toPascalCase(input: string): string;
export declare const SID_DENY_UNTRUSTED_ORGS = "DenyUntrustedOrgs";
export declare class K9PolicyFactory {
/**
* Deduplicate an array of principals while preserving original order of principals.
* Note that principals may contain either strings or objects, so naive array sorting
* produces unstable results.
*
* @param principals
*/
static deduplicatePrincipals(principals: Array<string | object>): Array<string | object>;
/** @internal */
_SUPPORTED_SERVICES: Set<string>;
/** @internal */
_K9CapabilityMapJSON: Object;
/** @internal */
_K9CapabilityMapByService: Map<string, Object>;
getActions(service: string, accessCapability: AccessCapability): Array<string>;
/** @internal */
_mergeAccessSpecs(target: IAccessSpec, addition: IAccessSpec): void;
mergeDesiredAccessSpecsByCapability(supportedCapabilities: Array<AccessCapability>, desiredAccess: Array<IAccessSpec>): Record<string, IAccessSpec>;
makeAllowStatements(serviceName: string, supportedCapabilities: Array<AccessCapability>, desiredAccess: Array<IAccessSpec>, resourceArns: Array<string>, usePascalCase?: boolean): Array<PolicyStatement>;
makeAllowStatement(sid: string, actions: Array<string>, principalArns: Array<string>, test: ArnConditionTest, resources: Array<string>, restrictToPrincipalOrgIDs?: Array<string>): PolicyStatement;
wasLikeUsed(accessSpecs: IAccessSpec[]): boolean;
getAllowedPrincipalArns(accessSpecs: IAccessSpec[]): Array<string>;
/**
* k9 wants to deny all AWS accounts and IAM principals not explicitly allowed; this *should*
* be straightforward, but it isn't because of the way aws-cdk merges and manipulates Principals.
* @return list of principals for a DenyEveryoneElse statement
*/
makeDenyEveryoneElsePrincipals(): ArnPrincipal[];
/**
* Create a DenyUntrustedOrgs statement that explicitly denies principals from
* untrusted orgs for org-restricted actions. This provides defense-in-depth
* beyond the implicit deny from org-constrained Allow statements.
*
* The StringNotEquals condition on aws:PrincipalOrgID is inherently safe for
* AWS service principals because the key is absent from their request context,
* so the condition is not satisfied and the Deny does not apply.
*
* @return a PolicyStatement with Effect Deny, or undefined if no access specs have org restrictions
* @internal
*/
_makeDenyUntrustedOrgsStatement(serviceName: string, supportedCapabilities: Array<AccessCapability>, accessSpecsByCapability: Map<AccessCapability, IAccessSpec>, resourceArns: Array<string>): PolicyStatement | undefined;
}