@flowcore/cli-plugin-iam 1.0.0 → 1.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.0](https://github.com/flowcore-io/cli-plugin-iam/compare/v1.0.0...v1.1.0) (2024-10-21)
4
+
5
+
6
+ ### Features
7
+
8
+ * :sparkles: added functionality to create and delete iam policies ([0916612](https://github.com/flowcore-io/cli-plugin-iam/commit/09166128f3d1180d019b301eab5ead0af3055dbd))
9
+ * :sparkles: added policy and role bindings to the iam api ([a1815a0](https://github.com/flowcore-io/cli-plugin-iam/commit/a1815a093ad6743b26dd3cf7a4cfd0c32a8b4326))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * :fire: removed console log on create policy ([6289f72](https://github.com/flowcore-io/cli-plugin-iam/commit/6289f72ec7eff9b00fc6a15e928e448ca6403294))
15
+ * :rotating_light: fixed linting errors ([b388ac6](https://github.com/flowcore-io/cli-plugin-iam/commit/b388ac6532d7d5c5c6c7fc1d401218bfbaa75b33))
16
+
3
17
  ## 1.0.0 (2024-09-29)
4
18
 
5
19
 
package/README.md CHANGED
@@ -18,7 +18,7 @@ $ npm install -g @flowcore/cli-plugin-iam
18
18
  $ iam COMMAND
19
19
  running command...
20
20
  $ iam (--version)
21
- @flowcore/cli-plugin-iam/1.0.0 linux-x64 node-v20.17.0
21
+ @flowcore/cli-plugin-iam/1.1.0 linux-x64 node-v20.18.0
22
22
  $ iam --help [COMMAND]
23
23
  USAGE
24
24
  $ iam COMMAND
@@ -51,7 +51,7 @@ DESCRIPTION
51
51
  Get a policy
52
52
  ```
53
53
 
54
- _See code: [src/commands/get/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.0.0/src/commands/get/policy.ts)_
54
+ _See code: [src/commands/get/policy.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.1.0/src/commands/get/policy.ts)_
55
55
 
56
56
  ## `iam get role [NAME]`
57
57
 
@@ -74,5 +74,5 @@ DESCRIPTION
74
74
  Get a role
75
75
  ```
76
76
 
77
- _See code: [src/commands/get/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.0.0/src/commands/get/role.ts)_
77
+ _See code: [src/commands/get/role.ts](https://github.com/flowcore-io/cli-plugin-iam/blob/v1.1.0/src/commands/get/role.ts)_
78
78
  <!-- commandsstop -->
@@ -37,9 +37,7 @@ export default class GetPolicy extends BaseCommand {
37
37
  const graphqlClient = await ClientFactory.create(this.cliConfiguration, this.logger, flags.json);
38
38
  const organizationService = new OrganizationService(graphqlClient);
39
39
  const organizations = await organizationService.getMyOrganizations();
40
- const iamClient = new IamApi({
41
- baseUrl: "https://iam.api.flowcore.io",
42
- });
40
+ const iamClient = new IamApi();
43
41
  const config = this.cliConfiguration.getConfig();
44
42
  const login = new ValidateLogin(config.login.url);
45
43
  await login.validate(config, this.cliConfiguration, !flags.json);
@@ -83,6 +81,7 @@ export default class GetPolicy extends BaseCommand {
83
81
  return {
84
82
  description: policy.description,
85
83
  documents: policy.policyDocuments,
84
+ flowcoreManaged: policy.flowcoreManaged,
86
85
  id: policy.id,
87
86
  name: policy.name,
88
87
  organization: organizationLink,
@@ -0,0 +1,10 @@
1
+ import type { CliConfiguration, Logger } from "@flowcore/cli-plugin-config";
2
+ import type { Config } from "@oclif/core";
3
+ import { type ApiRegistryService } from "@flowcore/cli-plugin-core";
4
+ declare const hook: (options: {
5
+ apiRegistry: ApiRegistryService;
6
+ cliConfiguration: CliConfiguration;
7
+ config: Config;
8
+ logger: Logger;
9
+ }) => Promise<void>;
10
+ export default hook;
@@ -0,0 +1,9 @@
1
+ import { ClientFactory, } from "@flowcore/cli-plugin-core";
2
+ import { IAMApply } from "../resource-types/iam-api-version.js";
3
+ import { OrganizationService } from "../services/organization.service.js";
4
+ const hook = async (options) => {
5
+ const graphqlClient = await ClientFactory.create(options.cliConfiguration, options.logger, false);
6
+ const organizationService = new OrganizationService(graphqlClient);
7
+ options.apiRegistry.register(new IAMApply(organizationService, options.cliConfiguration, options.logger));
8
+ };
9
+ export default hook;
@@ -0,0 +1,24 @@
1
+ import type { ApiRegistryEntry, BaseResource } from "@flowcore/cli-plugin-core";
2
+ import { type CliConfiguration, type Logger } from "@flowcore/cli-plugin-config";
3
+ import type { OrganizationService } from "../services/organization.service.js";
4
+ export declare class IAMApply implements ApiRegistryEntry {
5
+ private readonly organizationService;
6
+ private readonly cliConfiguration;
7
+ private readonly logger;
8
+ name: string;
9
+ private iamClient;
10
+ private organizations;
11
+ private policyBindingService;
12
+ private policyService;
13
+ private roleBindingService;
14
+ private roleService;
15
+ constructor(organizationService: OrganizationService, cliConfiguration: CliConfiguration, logger: Logger);
16
+ apply(resource: BaseResource, skipConfirmation: boolean): Promise<boolean>;
17
+ calculateApplyOrder(resources: BaseResource[]): BaseResource[];
18
+ delete(resource: BaseResource): Promise<boolean>;
19
+ fetchOrganizationId(tenant: string): Promise<{
20
+ id: string;
21
+ tenant: string;
22
+ } | undefined>;
23
+ getToken(): Promise<string>;
24
+ }
@@ -0,0 +1,106 @@
1
+ import { ValidateLogin, } from "@flowcore/cli-plugin-config";
2
+ import { Api as IamApi } from "../utils/clients/iam/Api.js";
3
+ import { PolicyService } from "./policy.resource.js";
4
+ import { PolicyBindingService } from "./policy-binding.resource.js";
5
+ import { RoleService } from "./role.resource.js";
6
+ import { RoleBindingService } from "./role-binding.resource.js";
7
+ const applyOrder = ["Policy", "PolicyBinding", "Role", "RoleBinding"];
8
+ export class IAMApply {
9
+ organizationService;
10
+ cliConfiguration;
11
+ logger;
12
+ name = "iam.flowcore.io/v1";
13
+ iamClient;
14
+ organizations = [];
15
+ policyBindingService;
16
+ policyService;
17
+ roleBindingService;
18
+ roleService;
19
+ constructor(organizationService, cliConfiguration, logger) {
20
+ this.organizationService = organizationService;
21
+ this.cliConfiguration = cliConfiguration;
22
+ this.logger = logger;
23
+ this.getToken = this.getToken.bind(this);
24
+ this.iamClient = new IamApi({
25
+ baseUrl: "https://iam.api.flowcore.io",
26
+ });
27
+ this.policyService = new PolicyService(this.iamClient, this.logger, this.getToken);
28
+ this.roleService = new RoleService(this.iamClient, this.logger, this.getToken);
29
+ this.roleBindingService = new RoleBindingService(this.iamClient, this.logger, this.getToken);
30
+ this.policyBindingService = new PolicyBindingService(this.iamClient, this.logger, this.getToken);
31
+ }
32
+ async apply(resource, skipConfirmation) {
33
+ const organization = await this.fetchOrganizationId(resource.metadata.tenant);
34
+ if (!organization) {
35
+ this.logger.fatal(`Tenant ${resource.metadata.tenant} not found, or you don't have access to it.`);
36
+ }
37
+ switch (resource.kind) {
38
+ case "Policy": {
39
+ return this.policyService.createNewPolicy(organization.id, resource, skipConfirmation);
40
+ }
41
+ case "Role": {
42
+ return this.roleService.createNewRole(organization.id, resource, skipConfirmation);
43
+ }
44
+ case "RoleBinding": {
45
+ return this.roleBindingService.createNewRoleBinding(organization.id, resource, skipConfirmation);
46
+ }
47
+ case "PolicyBinding": {
48
+ return this.policyBindingService.createNewPolicyBinding(organization.id, resource, skipConfirmation);
49
+ }
50
+ default: {
51
+ this.logger.fatal(`Unsupported resource kind: ${resource.kind}`);
52
+ }
53
+ }
54
+ }
55
+ calculateApplyOrder(resources) {
56
+ return resources.sort((a, b) => {
57
+ if (applyOrder.indexOf(a.kind) < applyOrder.indexOf(b.kind)) {
58
+ return -1;
59
+ }
60
+ return 1;
61
+ });
62
+ }
63
+ async delete(resource) {
64
+ const organization = await this.fetchOrganizationId(resource.metadata.tenant);
65
+ if (!organization) {
66
+ this.logger.fatal(`Tenant ${resource.metadata.tenant} not found, or you don't have access to it.`);
67
+ }
68
+ switch (resource.kind) {
69
+ case "Policy": {
70
+ return this.policyService.deletePolicy(organization.id, resource);
71
+ }
72
+ case "Role": {
73
+ return this.roleService.deleteRole(organization.id, resource);
74
+ }
75
+ case "RoleBinding": {
76
+ return this.roleBindingService.deleteRoleBinding(organization.id, resource);
77
+ }
78
+ case "PolicyBinding": {
79
+ return this.policyBindingService.deletePolicyBinding(organization.id, resource);
80
+ }
81
+ default: {
82
+ this.logger.fatal(`Unsupported resource kind: ${resource.kind}`);
83
+ }
84
+ }
85
+ }
86
+ async fetchOrganizationId(tenant) {
87
+ if (this.organizations.length === 0) {
88
+ const organizations = await this.organizationService.getMyOrganizations();
89
+ this.organizations = organizations.me.organizations.map((org) => ({
90
+ id: org.organization.id,
91
+ tenant: org.organization.org,
92
+ }));
93
+ }
94
+ return this.organizations.find((org) => org.tenant === tenant);
95
+ }
96
+ async getToken() {
97
+ const config = this.cliConfiguration.getConfig();
98
+ const login = new ValidateLogin(config.login.url);
99
+ await login.validate(config, this.cliConfiguration, false);
100
+ const { auth } = config;
101
+ if (!auth?.accessToken) {
102
+ this.logger.fatal("Not logged in, run 'flowcore login'");
103
+ }
104
+ return auth?.accessToken;
105
+ }
106
+ }
@@ -0,0 +1,82 @@
1
+ import type { Logger } from "@flowcore/cli-plugin-config";
2
+ import { z } from "zod";
3
+ import type { Api as IamApi } from "../utils/clients/iam/Api.js";
4
+ export declare const policyBindingDto: z.ZodObject<z.objectUtil.extendShape<{
5
+ apiVersion: z.ZodString;
6
+ kind: z.ZodString;
7
+ metadata: z.ZodObject<{
8
+ name: z.ZodString;
9
+ tenant: z.ZodString;
10
+ }, "strip", z.ZodTypeAny, {
11
+ name: string;
12
+ tenant: string;
13
+ }, {
14
+ name: string;
15
+ tenant: string;
16
+ }>;
17
+ }, {
18
+ spec: z.ZodObject<{
19
+ policy: z.ZodString;
20
+ subjects: z.ZodArray<z.ZodObject<{
21
+ id: z.ZodString;
22
+ type: z.ZodEnum<["user", "key"]>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ id: string;
25
+ type: "key" | "user";
26
+ }, {
27
+ id: string;
28
+ type: "key" | "user";
29
+ }>, "many">;
30
+ }, "strip", z.ZodTypeAny, {
31
+ policy: string;
32
+ subjects: {
33
+ id: string;
34
+ type: "key" | "user";
35
+ }[];
36
+ }, {
37
+ policy: string;
38
+ subjects: {
39
+ id: string;
40
+ type: "key" | "user";
41
+ }[];
42
+ }>;
43
+ }>, "strip", z.ZodTypeAny, {
44
+ kind: string;
45
+ apiVersion: string;
46
+ metadata: {
47
+ name: string;
48
+ tenant: string;
49
+ };
50
+ spec: {
51
+ policy: string;
52
+ subjects: {
53
+ id: string;
54
+ type: "key" | "user";
55
+ }[];
56
+ };
57
+ }, {
58
+ kind: string;
59
+ apiVersion: string;
60
+ metadata: {
61
+ name: string;
62
+ tenant: string;
63
+ };
64
+ spec: {
65
+ policy: string;
66
+ subjects: {
67
+ id: string;
68
+ type: "key" | "user";
69
+ }[];
70
+ };
71
+ }>;
72
+ export type PolicyBinding = z.infer<typeof policyBindingDto>;
73
+ export type ApiPolicyResource = Awaited<ReturnType<IamApi["getApiV1PolicyAssociationsOrganizationByOrganizationId"]>>["data"][0];
74
+ export type ApiPolicyAssociationResource = Awaited<ReturnType<IamApi["getApiV1PolicyAssociationsByPolicyId"]>>["data"];
75
+ export declare class PolicyBindingService {
76
+ private readonly iamClient;
77
+ private readonly logger;
78
+ private readonly getToken;
79
+ constructor(iamClient: IamApi, logger: Logger, getToken: () => Promise<string>);
80
+ createNewPolicyBinding(organizationId: string, policyBinding: unknown, skipConfirmation: boolean): Promise<boolean>;
81
+ deletePolicyBinding(organizationId: string, policyBinding: unknown): Promise<boolean>;
82
+ }
@@ -0,0 +1,203 @@
1
+ import { baseResourceDto } from "@flowcore/cli-plugin-core";
2
+ import enquirer from "enquirer";
3
+ import { diffString } from "json-diff";
4
+ import { z } from "zod";
5
+ export const policyBindingDto = baseResourceDto.extend({
6
+ spec: z.object({
7
+ policy: z.string(),
8
+ subjects: z.array(z.object({
9
+ id: z.string(),
10
+ type: z.enum(["user", "key"]),
11
+ })),
12
+ }),
13
+ });
14
+ export class PolicyBindingService {
15
+ iamClient;
16
+ logger;
17
+ getToken;
18
+ constructor(iamClient, logger, getToken) {
19
+ this.iamClient = iamClient;
20
+ this.logger = logger;
21
+ this.getToken = getToken;
22
+ }
23
+ async createNewPolicyBinding(organizationId, policyBinding, skipConfirmation) {
24
+ const parsedPolicyBinding = policyBindingDto.parse(policyBinding);
25
+ try {
26
+ const policies = await this.iamClient.getApiV1PolicyAssociationsOrganizationByOrganizationId(organizationId, {
27
+ headers: {
28
+ Authorization: `Bearer ${await this.getToken()}`,
29
+ },
30
+ });
31
+ const existingPolicy = policies.data.find((p) => p.name === parsedPolicyBinding.spec.policy);
32
+ if (!existingPolicy) {
33
+ this.logger.error(`Policy ${parsedPolicyBinding.spec.policy} not found`);
34
+ return false;
35
+ }
36
+ const associations = await this.iamClient.getApiV1PolicyAssociationsByPolicyId(existingPolicy.id, {
37
+ headers: {
38
+ Authorization: `Bearer ${await this.getToken()}`,
39
+ },
40
+ });
41
+ const usersToDelete = [];
42
+ for (const userAssociation of associations.data.users.filter((u) => u.policyId !== existingPolicy.id)) {
43
+ if (!parsedPolicyBinding.spec.subjects.find((s) => s.type === "user" && s.id === userAssociation.userId)) {
44
+ usersToDelete.push(userAssociation.userId);
45
+ }
46
+ }
47
+ const keysToDelete = [];
48
+ for (const keyAssociation of associations.data.keys.filter((k) => k.policyId !== existingPolicy.id)) {
49
+ if (!parsedPolicyBinding.spec.subjects.find((s) => s.type === "key" && s.id === keyAssociation.keyId)) {
50
+ keysToDelete.push(keyAssociation.keyId);
51
+ }
52
+ }
53
+ if (!skipConfirmation) {
54
+ const diffObject = {
55
+ keys: associations.data.keys.filter((k) => !keysToDelete.includes(k.keyId)),
56
+ users: associations.data.users.filter((u) => !usersToDelete.includes(u.userId)),
57
+ };
58
+ this.logger.info("Modifying the following:");
59
+ this.logger.info(`${diffString(associations.data.users.map((u) => u.userId), diffObject.users, { color: true, full: true })}`);
60
+ this.logger.info(`${diffString(associations.data.keys.map((k) => k.keyId), diffObject.keys, { color: true, full: true })}`);
61
+ const { confirm } = await enquirer.prompt([
62
+ {
63
+ message: `Are you sure you want to remove ${usersToDelete.length} users and ${keysToDelete.length} keys from policy ${existingPolicy.name}?`,
64
+ name: "confirm",
65
+ type: "confirm",
66
+ },
67
+ ]);
68
+ if (!confirm) {
69
+ return false;
70
+ }
71
+ }
72
+ let changed = keysToDelete.length > 0 || usersToDelete.length > 0;
73
+ for (const userId of usersToDelete) {
74
+ const result = await this.iamClient.deleteApiV1PolicyAssociationsUserByUserId(userId, { policyId: existingPolicy.id }, {
75
+ headers: {
76
+ Authorization: `Bearer ${await this.getToken()}`,
77
+ },
78
+ });
79
+ if (result.status !== 200) {
80
+ this.logger.error(`Failed to delete user ${userId} from policy ${existingPolicy.name}: ${result.statusText}`);
81
+ }
82
+ }
83
+ for (const keyId of keysToDelete) {
84
+ const result = await this.iamClient.deleteApiV1PolicyAssociationsKeyByKeyId(keyId, { policyId: existingPolicy.id }, {
85
+ headers: {
86
+ Authorization: `Bearer ${await this.getToken()}`,
87
+ },
88
+ });
89
+ if (result.status !== 200) {
90
+ this.logger.error(`Failed to delete key ${keyId} from policy ${existingPolicy.name}: ${result.statusText}`);
91
+ }
92
+ }
93
+ for (const subject of parsedPolicyBinding.spec.subjects) {
94
+ switch (subject.type) {
95
+ case "user": {
96
+ const existingAssociation = associations.data.users.find((a) => a.userId === subject.id);
97
+ if (existingAssociation) {
98
+ this.logger.debug(`User ${subject.id} already bound to policy ${existingPolicy.name}`);
99
+ continue;
100
+ }
101
+ const result = await this.iamClient.postApiV1PolicyAssociationsUserByUserId(subject.id, { policyId: existingPolicy.id }, {
102
+ headers: {
103
+ Authorization: `Bearer ${await this.getToken()}`,
104
+ },
105
+ });
106
+ if (result.status !== 200) {
107
+ this.logger.error(`Failed to bind user ${subject.id} to policy ${existingPolicy.name}: ${result.statusText}`);
108
+ }
109
+ changed = true;
110
+ break;
111
+ }
112
+ case "key": {
113
+ const existingAssociation = associations.data.keys.find((a) => a.keyId === subject.id);
114
+ if (existingAssociation) {
115
+ this.logger.debug(`Key ${subject.id} already bound to policy ${existingPolicy.name}`);
116
+ continue;
117
+ }
118
+ const result = await this.iamClient.postApiV1PolicyAssociationsKeyByKeyId(subject.id, { policyId: existingPolicy.id }, {
119
+ headers: {
120
+ Authorization: `Bearer ${await this.getToken()}`,
121
+ },
122
+ });
123
+ if (result.status !== 200) {
124
+ this.logger.error(`Failed to bind key ${subject.id} to policy ${existingPolicy.name}: ${result.statusText}`);
125
+ }
126
+ changed = true;
127
+ break;
128
+ }
129
+ }
130
+ }
131
+ return changed;
132
+ }
133
+ catch (error) {
134
+ if (typeof error === "object" && error !== null && "error" in error) {
135
+ const err = error;
136
+ this.logger.fatal(`Failed to create policy binding with error(${err.error.status} - ${err.error.code}): ${err.error.message}`);
137
+ }
138
+ else {
139
+ this.logger.fatal(`Failed to create policy binding with unknown error: ${error}`);
140
+ }
141
+ }
142
+ }
143
+ async deletePolicyBinding(organizationId, policyBinding) {
144
+ const parsedPolicyBinding = policyBindingDto.parse(policyBinding);
145
+ try {
146
+ const policies = await this.iamClient.getApiV1PolicyAssociationsOrganizationByOrganizationId(organizationId, {
147
+ headers: {
148
+ Authorization: `Bearer ${await this.getToken()}`,
149
+ },
150
+ });
151
+ const targetPolicy = policies.data.find((p) => p.name === parsedPolicyBinding.spec.policy);
152
+ if (!targetPolicy) {
153
+ this.logger.fatal(`Policy ${parsedPolicyBinding.spec.policy} not found`);
154
+ }
155
+ const associations = await this.iamClient.getApiV1PolicyAssociationsByPolicyId(targetPolicy.id, {
156
+ headers: {
157
+ Authorization: `Bearer ${await this.getToken()}`,
158
+ },
159
+ });
160
+ for (const subject of parsedPolicyBinding.spec.subjects) {
161
+ switch (subject.type) {
162
+ case "user": {
163
+ const existingAssociation = associations.data.users.find((a) => a.userId === subject.id);
164
+ if (!existingAssociation) {
165
+ this.logger.error(`User ${subject.id} not bound to policy ${targetPolicy.id}`);
166
+ continue;
167
+ }
168
+ const result = await this.iamClient.deleteApiV1PolicyAssociationsUserByUserId(subject.id, { policyId: targetPolicy.id }, {
169
+ headers: {
170
+ Authorization: `Bearer ${await this.getToken()}`,
171
+ },
172
+ });
173
+ if (result.status !== 200) {
174
+ this.logger.error(`Failed to delete policy binding for user ${subject.id}: ${result.statusText}`);
175
+ }
176
+ break;
177
+ }
178
+ case "key": {
179
+ const result = await this.iamClient.deleteApiV1PolicyAssociationsKeyByKeyId(subject.id, { policyId: targetPolicy.id }, {
180
+ headers: {
181
+ Authorization: `Bearer ${await this.getToken()}`,
182
+ },
183
+ });
184
+ if (result.status !== 200) {
185
+ this.logger.error(`Failed to delete policy binding for key ${subject.id}: ${result.statusText}`);
186
+ }
187
+ break;
188
+ }
189
+ }
190
+ }
191
+ return true;
192
+ }
193
+ catch (error) {
194
+ if (typeof error === "object" && error !== null && "error" in error) {
195
+ const err = error;
196
+ this.logger.fatal(`Failed to delete policy with error(${err.error.status} - ${err.error.code}): ${err.error.message}`);
197
+ }
198
+ else {
199
+ this.logger.fatal(`Failed to delete policy with unknown error: ${error}`);
200
+ }
201
+ }
202
+ }
203
+ }
@@ -0,0 +1,110 @@
1
+ import type { Logger } from "@flowcore/cli-plugin-config";
2
+ import { z } from "zod";
3
+ import type { Api as IamApi } from "../utils/clients/iam/Api.js";
4
+ export declare enum PolicyDocumentAction {
5
+ ALL = "*",
6
+ FETCH = "FETCH",
7
+ INGEST = "INGEST",
8
+ READ = "READ",
9
+ WRITE = "WRITE"
10
+ }
11
+ export declare const policyDto: z.ZodObject<z.objectUtil.extendShape<{
12
+ apiVersion: z.ZodString;
13
+ kind: z.ZodString;
14
+ metadata: z.ZodObject<{
15
+ name: z.ZodString;
16
+ tenant: z.ZodString;
17
+ }, "strip", z.ZodTypeAny, {
18
+ name: string;
19
+ tenant: string;
20
+ }, {
21
+ name: string;
22
+ tenant: string;
23
+ }>;
24
+ }, {
25
+ spec: z.ZodObject<{
26
+ description: z.ZodOptional<z.ZodString>;
27
+ flowcoreManaged: z.ZodOptional<z.ZodBoolean>;
28
+ policyDocuments: z.ZodArray<z.ZodObject<{
29
+ action: z.ZodUnion<[z.ZodArray<z.ZodNativeEnum<typeof PolicyDocumentAction>, "many">, z.ZodNativeEnum<typeof PolicyDocumentAction>]>;
30
+ resource: z.ZodString;
31
+ statementId: z.ZodOptional<z.ZodString>;
32
+ }, "strip", z.ZodTypeAny, {
33
+ action: PolicyDocumentAction | PolicyDocumentAction[];
34
+ resource: string;
35
+ statementId?: string | undefined;
36
+ }, {
37
+ action: PolicyDocumentAction | PolicyDocumentAction[];
38
+ resource: string;
39
+ statementId?: string | undefined;
40
+ }>, "many">;
41
+ principal: z.ZodOptional<z.ZodString>;
42
+ version: z.ZodString;
43
+ }, "strip", z.ZodTypeAny, {
44
+ version: string;
45
+ policyDocuments: {
46
+ action: PolicyDocumentAction | PolicyDocumentAction[];
47
+ resource: string;
48
+ statementId?: string | undefined;
49
+ }[];
50
+ description?: string | undefined;
51
+ flowcoreManaged?: boolean | undefined;
52
+ principal?: string | undefined;
53
+ }, {
54
+ version: string;
55
+ policyDocuments: {
56
+ action: PolicyDocumentAction | PolicyDocumentAction[];
57
+ resource: string;
58
+ statementId?: string | undefined;
59
+ }[];
60
+ description?: string | undefined;
61
+ flowcoreManaged?: boolean | undefined;
62
+ principal?: string | undefined;
63
+ }>;
64
+ }>, "strip", z.ZodTypeAny, {
65
+ kind: string;
66
+ apiVersion: string;
67
+ metadata: {
68
+ name: string;
69
+ tenant: string;
70
+ };
71
+ spec: {
72
+ version: string;
73
+ policyDocuments: {
74
+ action: PolicyDocumentAction | PolicyDocumentAction[];
75
+ resource: string;
76
+ statementId?: string | undefined;
77
+ }[];
78
+ description?: string | undefined;
79
+ flowcoreManaged?: boolean | undefined;
80
+ principal?: string | undefined;
81
+ };
82
+ }, {
83
+ kind: string;
84
+ apiVersion: string;
85
+ metadata: {
86
+ name: string;
87
+ tenant: string;
88
+ };
89
+ spec: {
90
+ version: string;
91
+ policyDocuments: {
92
+ action: PolicyDocumentAction | PolicyDocumentAction[];
93
+ resource: string;
94
+ statementId?: string | undefined;
95
+ }[];
96
+ description?: string | undefined;
97
+ flowcoreManaged?: boolean | undefined;
98
+ principal?: string | undefined;
99
+ };
100
+ }>;
101
+ export type Policy = z.infer<typeof policyDto>;
102
+ export type ApiPolicyResource = Awaited<ReturnType<IamApi["getApiV1PolicyAssociationsOrganizationByOrganizationId"]>>["data"][0];
103
+ export declare class PolicyService {
104
+ private readonly iamClient;
105
+ private readonly logger;
106
+ private readonly getToken;
107
+ constructor(iamClient: IamApi, logger: Logger, getToken: () => Promise<string>);
108
+ createNewPolicy(organizationId: string, policy: unknown, skipConfirmation: boolean): Promise<boolean>;
109
+ deletePolicy(organizationId: string, policy: unknown): Promise<boolean>;
110
+ }