Skip to content

Commit 8dd5238

Browse files
committed
fix(policy): use a dedicated TriggerRule on DataStewardPolicy instead of mixing into EditRule
1 parent cde9cab commit 8dd5238

6 files changed

Lines changed: 87 additions & 21 deletions

File tree

openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v1129/Migration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.openmetadata.service.migration.mysql.v1129;
22

3-
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultPolicies;
3+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultBotPolicies;
4+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerRuleToDataStewardPolicy;
45

56
import lombok.SneakyThrows;
67
import org.openmetadata.service.migration.api.MigrationProcessImpl;
@@ -15,6 +16,7 @@ public Migration(MigrationFile migrationFile) {
1516
@Override
1617
@SneakyThrows
1718
public void runDataMigration() {
18-
addTriggerOperationToDefaultPolicies(collectionDAO);
19+
addTriggerOperationToDefaultBotPolicies(collectionDAO);
20+
addTriggerRuleToDataStewardPolicy(collectionDAO);
1921
}
2022
}

openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v1130/Migration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.openmetadata.service.migration.mysql.v1130;
22

3-
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultPolicies;
3+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultBotPolicies;
4+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerRuleToDataStewardPolicy;
45

56
import lombok.SneakyThrows;
67
import lombok.extern.slf4j.Slf4j;
@@ -33,6 +34,7 @@ public void runDataMigration() {
3334
LOG.error("v1130 glossaryTerm version relatedTerms transform failed; re-run to retry.", e);
3435
}
3536
MigrationUtil.addTableColumnSearchSettings();
36-
addTriggerOperationToDefaultPolicies(collectionDAO);
37+
addTriggerOperationToDefaultBotPolicies(collectionDAO);
38+
addTriggerRuleToDataStewardPolicy(collectionDAO);
3739
}
3840
}

openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v1129/Migration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.openmetadata.service.migration.postgres.v1129;
22

3-
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultPolicies;
3+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultBotPolicies;
4+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerRuleToDataStewardPolicy;
45

56
import lombok.SneakyThrows;
67
import org.openmetadata.service.migration.api.MigrationProcessImpl;
@@ -15,6 +16,7 @@ public Migration(MigrationFile migrationFile) {
1516
@Override
1617
@SneakyThrows
1718
public void runDataMigration() {
18-
addTriggerOperationToDefaultPolicies(collectionDAO);
19+
addTriggerOperationToDefaultBotPolicies(collectionDAO);
20+
addTriggerRuleToDataStewardPolicy(collectionDAO);
1921
}
2022
}

openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v1130/Migration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.openmetadata.service.migration.postgres.v1130;
22

3-
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultPolicies;
3+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerOperationToDefaultBotPolicies;
4+
import static org.openmetadata.service.migration.utils.v1129.MigrationUtil.addTriggerRuleToDataStewardPolicy;
45

56
import lombok.SneakyThrows;
67
import lombok.extern.slf4j.Slf4j;
@@ -33,6 +34,7 @@ public void runDataMigration() {
3334
LOG.error("v1130 glossaryTerm version relatedTerms transform failed; re-run to retry.", e);
3435
}
3536
MigrationUtil.addTableColumnSearchSettings();
36-
addTriggerOperationToDefaultPolicies(collectionDAO);
37+
addTriggerOperationToDefaultBotPolicies(collectionDAO);
38+
addTriggerRuleToDataStewardPolicy(collectionDAO);
3739
}
3840
}

openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v1129/MigrationUtil.java

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,91 @@
44

55
import java.util.List;
66
import lombok.extern.slf4j.Slf4j;
7+
import org.openmetadata.schema.entity.policies.Policy;
8+
import org.openmetadata.schema.entity.policies.accessControl.Rule;
9+
import org.openmetadata.schema.type.Include;
710
import org.openmetadata.schema.type.MetadataOperation;
11+
import org.openmetadata.schema.utils.JsonUtils;
12+
import org.openmetadata.service.Entity;
13+
import org.openmetadata.service.exception.EntityNotFoundException;
814
import org.openmetadata.service.jdbi3.CollectionDAO;
15+
import org.openmetadata.service.jdbi3.PolicyRepository;
916

1017
@Slf4j
1118
public class MigrationUtil {
1219

1320
private MigrationUtil() {}
1421

1522
/**
16-
* Retrofits default seeded policies that grant broad edit capability with the {@code Trigger}
17-
* operation, keeping pre-existing customer behavior intact after {@code /trigger} starts
18-
* enforcing authz (GH-27962).
23+
* Retrofits seeded bot policies that grant broad {@code EditAll} on {@code ["All"]} resources
24+
* with the {@code Trigger} operation. Pre-fix these identities could trigger pipelines because
25+
* {@code /trigger} skipped authz; the migration preserves that behavior under the new authz
26+
* enforcement (GH-27962).
1927
*
20-
* <p>Targets the rules whose resources are {@code "All"} and that already grant {@code EditAll}
21-
* (the broad-bot allow rules) plus {@code DataStewardPolicy} which grants {@code EditOwners} —
22-
* stewards can already reach trigger via the ownership-edit escalation path, so granting it
23-
* explicitly aligns the policy with the effective capability and improves the audit trail.
24-
*
25-
* <p>Each call is idempotent via {@link
28+
* <p>Each entry is idempotent via {@link
2629
* org.openmetadata.service.migration.utils.v160.MigrationUtil#addOperationsToPolicyRule}.
2730
*/
28-
public static void addTriggerOperationToDefaultPolicies(CollectionDAO collectionDAO) {
31+
public static void addTriggerOperationToDefaultBotPolicies(CollectionDAO collectionDAO) {
2932
record PolicyRule(String policy, String rule) {}
3033
List<PolicyRule> targets =
3134
List.of(
3235
new PolicyRule("IngestionBotPolicy", "IngestionBotRule-Allow"),
3336
new PolicyRule("LineageBotPolicy", "LineageBotRule-Allow"),
3437
new PolicyRule("ProfilerBotPolicy", "ProfilerBotBotRule-Allow"),
3538
new PolicyRule("QualityBotPolicy", "QualityBotBotRule-Allow"),
36-
new PolicyRule("UsageBotPolicy", "UsageBotRule-Allow-Usage"),
37-
new PolicyRule("DataStewardPolicy", "DataStewardPolicy-EditRule"));
39+
new PolicyRule("UsageBotPolicy", "UsageBotRule-Allow-Usage"));
3840
for (PolicyRule t : targets) {
3941
addOperationsToPolicyRule(
4042
t.policy(), t.rule(), List.of(MetadataOperation.TRIGGER), collectionDAO);
4143
}
4244
}
45+
46+
/**
47+
* Adds a dedicated {@code DataStewardPolicy-TriggerRule} to the existing {@code
48+
* DataStewardPolicy} if not already present. Data stewards already have {@code EditOwners} on
49+
* all resources, so they could already reach trigger via an ownership rewrite; this rule makes
50+
* the capability explicit for audit clarity rather than burying it inside the existing edit
51+
* rule.
52+
*
53+
* <p>Mirrors the new-rule shape used by {@code
54+
* v180.MigrationUtil.addDenyDisplayNameRuleToBotPolicies}. Idempotent — skips when the rule
55+
* already exists.
56+
*/
57+
public static void addTriggerRuleToDataStewardPolicy(CollectionDAO collectionDAO) {
58+
PolicyRepository repository = (PolicyRepository) Entity.getEntityRepository(Entity.POLICY);
59+
try {
60+
Policy policy = repository.findByName("DataStewardPolicy", Include.NON_DELETED);
61+
boolean hasTriggerRule =
62+
policy.getRules().stream()
63+
.anyMatch(
64+
r ->
65+
"DataStewardPolicy-TriggerRule".equals(r.getName())
66+
&& r.getEffect() == Rule.Effect.ALLOW
67+
&& r.getOperations() != null
68+
&& r.getOperations().contains(MetadataOperation.TRIGGER));
69+
if (!hasTriggerRule) {
70+
Rule triggerRule =
71+
new Rule()
72+
.withName("DataStewardPolicy-TriggerRule")
73+
.withDescription(
74+
"Allow data stewards to trigger ingestion pipelines. Stewards already have "
75+
+ "EditOwners on all resources and can reach trigger via an ownership "
76+
+ "rewrite; this rule makes the capability explicit for audit clarity.")
77+
.withResources(List.of("all"))
78+
.withOperations(List.of(MetadataOperation.TRIGGER))
79+
.withEffect(Rule.Effect.ALLOW);
80+
policy.getRules().add(triggerRule);
81+
collectionDAO
82+
.policyDAO()
83+
.update(policy.getId(), policy.getFullyQualifiedName(), JsonUtils.pojoToJson(policy));
84+
LOG.info("Added DataStewardPolicy-TriggerRule to DataStewardPolicy");
85+
} else {
86+
LOG.debug("DataStewardPolicy already has TriggerRule, skipping");
87+
}
88+
} catch (EntityNotFoundException ex) {
89+
LOG.warn("DataStewardPolicy not found, skipping TriggerRule addition");
90+
} catch (Exception e) {
91+
LOG.error("Failed to add TriggerRule to DataStewardPolicy: {}", e.getMessage(), e);
92+
}
93+
}
4394
}

openmetadata-service/src/main/resources/json/data/policy/DataStewardPolicy.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@
1010
{
1111
"name": "DataStewardPolicy-EditRule",
1212
"resources" : ["all"],
13-
"operations": ["ViewAll", "EditDescription", "EditDisplayName", "EditLineage", "EditOwners", "EditTags", "EditTier", "EditGlossaryTerms", "EditCertification", "Trigger"],
13+
"operations": ["ViewAll", "EditDescription", "EditDisplayName", "EditLineage", "EditOwners", "EditTags", "EditTier", "EditGlossaryTerms", "EditCertification"],
14+
"effect": "allow"
15+
},
16+
{
17+
"name": "DataStewardPolicy-TriggerRule",
18+
"description": "Allow data stewards to trigger ingestion pipelines. Stewards already have EditOwners on all resources and can reach trigger via an ownership rewrite; this rule makes the capability explicit for audit clarity.",
19+
"resources": ["all"],
20+
"operations": ["Trigger"],
1421
"effect": "allow"
1522
}
1623
]

0 commit comments

Comments
 (0)