Skip to content

Commit

Permalink
privileges(refactor): consolidate individual sys op privileges (datah…
Browse files Browse the repository at this point in the history
  • Loading branch information
david-leifker authored Oct 7, 2024
1 parent 7bdb7bb commit 5ad15a7
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 34 deletions.
32 changes: 12 additions & 20 deletions docs/authorization/policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,18 @@ These privileges are for DataHub operators to access & manage the administrative

#### System Management

| Platform Privileges | Description |
|-----------------------------------------------|------------------------------------------------------------------------|
| Restore Indices API[^1] | Allow actor to use the Restore Indices API. | |
| Get Timeseries index sizes API[^1] | Allow actor to use the get Timeseries indices size API. |
| Truncate timeseries aspect index size API[^1] | Allow actor to use the API to truncate a timeseries index. |
| Get ES task status API[^1] | Allow actor to use the get task status API for an ElasticSearch task. |
| Enable/Disable Writeability API[^1] | Allow actor to enable or disable GMS writeability for data migrations. |
| Apply Retention API[^1] | Allow actor to apply retention using the API. |
| Analytics API access[^1] | Allow actor to use API read access to raw analytics data. |
| Manage System Operations | Allow actor to manage system operation controls. |
| Platform Privileges | Description |
|-----------------------------------------------|----------------------------------------------------------------------------------------------------------|
| Restore Indices API[^1] | Allow actor to use the Restore Indices API. | |
| Get Timeseries index sizes API[^1] | Allow actor to use the get Timeseries indices size API. |
| Truncate timeseries aspect index size API[^1] | Allow actor to use the API to truncate a timeseries index. |
| Get ES task status API[^1] | Allow actor to use the get task status API for an ElasticSearch task. |
| Enable/Disable Writeability API[^1] | Allow actor to enable or disable GMS writeability for data migrations. |
| Apply Retention API[^1] | Allow actor to apply retention using the API. |
| Analytics API access[^1] | Allow actor to use API read access to raw analytics data. |
| Explain ElasticSearch Query API[^1] | Allow actor to use the Operations API explain endpoint. |
| Produce Platform Event API[^1] | Allow actor to produce Platform Events using the API. |
| Manage System Operations | Allow actor to manage system operation controls. This setting includes all System Management privileges. |

[^1]: Only active if REST_API_AUTHORIZATION_ENABLED is true
[^2]: DataHub Cloud only
Expand Down Expand Up @@ -262,16 +264,6 @@ These privileges are to view & modify any entity within DataHub.
[^1]: Only active if REST_API_AUTHORIZATION_ENABLED is true
[^2]: DataHub Cloud only

#### System Management

| System Privileges | Description |
|-------------------------------------|--------------------------------------------------------------------------------------------|
| Explain ElasticSearch Query API[^1] | Allow actor to use the Operations API explain endpoint. |
| Produce Platform Event API[^1] | Allow actor to produce Platform Events using the API. |

[^1]: Only active if REST_API_AUTHORIZATION_ENABLED is true
[^2]: DataHub Cloud only

### Specific Entity-level Privileges
These privileges are not generalizable.

Expand Down
2 changes: 2 additions & 0 deletions docs/how/updating-datahub.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ This file documents any backwards-incompatible changes in DataHub and assists pe

### Other Notable Changes

- #11549 - Manage Operations Privilege is extended from throttle control to all system management and operations APIs.

## 0.14.1

### Breaking Changes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static com.linkedin.metadata.authorization.Disjunctive.DENY_ACCESS;
import static com.linkedin.metadata.authorization.PoliciesConfig.API_ENTITY_PRIVILEGE_MAP;
import static com.linkedin.metadata.authorization.PoliciesConfig.API_PRIVILEGE_MAP;
import static com.linkedin.metadata.authorization.PoliciesConfig.MANAGE_SYSTEM_OPERATIONS_PRIVILEGE;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
Expand Down Expand Up @@ -304,6 +305,30 @@ public static boolean isAPIAuthorized(
return isAPIAuthorized(session, Disjunctive.disjoint(privilege), (EntitySpec) null);
}

/**
* Allow specific privilege OR MANAGE_SYSTEM_OPERATIONS_PRIVILEGE
*
* @param session authorization session
* @param privilege specific privilege
* @return authorized status
*/
public static boolean isAPIOperationsAuthorized(
@Nonnull final AuthorizationSession session,
@Nonnull final PoliciesConfig.Privilege privilege) {
return isAPIAuthorized(
session,
Disjunctive.disjoint(privilege, MANAGE_SYSTEM_OPERATIONS_PRIVILEGE),
(EntitySpec) null);
}

public static boolean isAPIOperationsAuthorized(
@Nonnull final AuthorizationSession session,
@Nonnull final PoliciesConfig.Privilege privilege,
@Nullable final EntitySpec resource) {
return isAPIAuthorized(
session, Disjunctive.disjoint(privilege, MANAGE_SYSTEM_OPERATIONS_PRIVILEGE), resource);
}

private static boolean isAPIAuthorized(
@Nonnull final AuthorizationSession session,
@Nonnull final Disjunctive<Conjunctive<PoliciesConfig.Privilege>> privileges,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ public ResponseEntity<String> getIndexSizes(HttpServletRequest request) {
authentication,
true);

if (!AuthUtil.isAPIAuthorized(opContext, PoliciesConfig.GET_TIMESERIES_INDEX_SIZES_PRIVILEGE)) {
if (!AuthUtil.isAPIOperationsAuthorized(
opContext, PoliciesConfig.GET_TIMESERIES_INDEX_SIZES_PRIVILEGE)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN)
.body(String.format(actorUrnStr + " is not authorized to get timeseries index sizes"));
}
Expand Down Expand Up @@ -255,7 +256,7 @@ public ResponseEntity<ExplainResponse> explainSearchQuery(
}
});

if (!AuthUtil.isAPIAuthorized(opContext, PoliciesConfig.ES_EXPLAIN_QUERY_PRIVILEGE)) {
if (!AuthUtil.isAPIOperationsAuthorized(opContext, PoliciesConfig.ES_EXPLAIN_QUERY_PRIVILEGE)) {
log.error("{} is not authorized to get explain queries", actorUrnStr);
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(null);
}
Expand Down Expand Up @@ -363,7 +364,7 @@ public ResponseEntity<String> explainSearchQueryDiff(
}
});

if (!AuthUtil.isAPIAuthorized(opContext, PoliciesConfig.ES_EXPLAIN_QUERY_PRIVILEGE)) {
if (!AuthUtil.isAPIOperationsAuthorized(opContext, PoliciesConfig.ES_EXPLAIN_QUERY_PRIVILEGE)) {
log.error("{} is not authorized to get explain queries", actorUrnStr);
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(null);
}
Expand Down Expand Up @@ -449,7 +450,7 @@ public ResponseEntity<List<RestoreIndicesResult>> restoreIndices(
authentication,
true);

if (!AuthUtil.isAPIAuthorized(opContext, PoliciesConfig.RESTORE_INDICES_PRIVILEGE)) {
if (!AuthUtil.isAPIOperationsAuthorized(opContext, PoliciesConfig.RESTORE_INDICES_PRIVILEGE)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}

Expand Down Expand Up @@ -492,7 +493,7 @@ public ResponseEntity<List<RestoreIndicesResult>> restoreIndices(
authentication,
true);

if (!AuthUtil.isAPIAuthorized(opContext, PoliciesConfig.RESTORE_INDICES_PRIVILEGE)) {
if (!AuthUtil.isAPIOperationsAuthorized(opContext, PoliciesConfig.RESTORE_INDICES_PRIVILEGE)) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.datahub.authorization.AuthUtil.isAPIAuthorized;
import static com.datahub.authorization.AuthUtil.isAPIAuthorizedEntityUrns;
import static com.datahub.authorization.AuthUtil.isAPIAuthorizedUrns;
import static com.datahub.authorization.AuthUtil.isAPIOperationsAuthorized;
import static com.linkedin.metadata.authorization.ApiGroup.COUNTS;
import static com.linkedin.metadata.authorization.ApiGroup.ENTITY;
import static com.linkedin.metadata.authorization.ApiGroup.TIMESERIES;
Expand Down Expand Up @@ -372,7 +373,7 @@ public Task<String> restoreIndices(
systemOperationContext, RequestContext.builder().buildRestli(authentication.getActor().toUrnStr(),
getContext(), ACTION_RESTORE_INDICES), _authorizer, authentication, true);

if (!isAPIAuthorized(
if (!isAPIOperationsAuthorized(
opContext,
PoliciesConfig.RESTORE_INDICES_PRIVILEGE)) {
throw new RestLiServiceException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ public Task<Void> setWriteable(
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(),
"setWriteable"), authorizer, auth, true);

if (!isAPIAuthorized(
if (!isAPIOperationsAuthorized(
opContext,
PoliciesConfig.SET_WRITEABLE_PRIVILEGE)) {
throw new RestLiServiceException(
Expand Down Expand Up @@ -1168,7 +1168,7 @@ public Task<String> applyRetention(
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(),
ACTION_APPLY_RETENTION, resourceSpec.getType()), authorizer, auth, true);

if (!isAPIAuthorized(
if (!isAPIOperationsAuthorized(
opContext,
PoliciesConfig.APPLY_RETENTION_PRIVILEGE,
resourceSpec)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.linkedin.metadata.resources.operations;

import static com.datahub.authorization.AuthUtil.isAPIAuthorized;
import static com.datahub.authorization.AuthUtil.isAPIOperationsAuthorized;
import static com.linkedin.metadata.resources.restli.RestliConstants.*;
import static com.linkedin.metadata.utils.CriterionUtils.buildCriterion;

Expand Down Expand Up @@ -136,7 +137,7 @@ public Task<String> getTaskStatus(
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(),
ACTION_GET_ES_TASK_STATUS), _authorizer, auth, true);

if (!isAPIAuthorized(
if (!isAPIOperationsAuthorized(
opContext,
PoliciesConfig.GET_ES_TASK_STATUS_PRIVILEGE)) {
throw new RestLiServiceException(
Expand Down Expand Up @@ -199,7 +200,7 @@ public Task<TimeseriesIndicesSizesResult> getIndexSizes() {
systemOperationContext, RequestContext.builder().buildRestli(auth.getActor().toUrnStr(), getContext(),
ACTION_GET_INDEX_SIZES, List.of()), _authorizer, auth, true);

if (!isAPIAuthorized(
if (!isAPIOperationsAuthorized(
opContext,
PoliciesConfig.GET_TIMESERIES_INDEX_SIZES_PRIVILEGE)) {
throw new RestLiServiceException(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.linkedin.metadata.resources.platform;

import static com.datahub.authorization.AuthUtil.isAPIAuthorized;
import static com.datahub.authorization.AuthUtil.isAPIOperationsAuthorized;

import com.datahub.authentication.Authentication;
import com.datahub.authentication.AuthenticationContext;
Expand Down Expand Up @@ -63,7 +64,7 @@ public Task<Void> producePlatformEvent(
ACTION_PRODUCE_PLATFORM_EVENT), _authorizer,
auth, true);

if (!isAPIAuthorized(
if (!isAPIOperationsAuthorized(
opContext,
PoliciesConfig.PRODUCE_PLATFORM_EVENT_PRIVILEGE)) {
throw new RestLiServiceException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public class PoliciesConfig {
Privilege.of(
"MANAGE_SYSTEM_OPERATIONS",
"Manage System Operations",
"Allow access to system operations APIs and controls.");
"Allow access to all system operations/management APIs and controls.");

public static final List<Privilege> PLATFORM_PRIVILEGES =
ImmutableList.of(
Expand Down Expand Up @@ -877,13 +877,19 @@ public class PoliciesConfig {
.put(ApiOperation.CREATE, DENY_ACCESS)
.put(
ApiOperation.READ,
Disjunctive.disjoint(VIEW_ANALYTICS_PRIVILEGE, GET_ANALYTICS_PRIVILEGE))
Disjunctive.disjoint(
VIEW_ANALYTICS_PRIVILEGE,
GET_ANALYTICS_PRIVILEGE,
MANAGE_SYSTEM_OPERATIONS_PRIVILEGE))
.put(ApiOperation.UPDATE, DENY_ACCESS)
.put(ApiOperation.DELETE, DENY_ACCESS)
.put(
ApiOperation.EXISTS,
Disjunctive.disjoint(
VIEW_ANALYTICS_PRIVILEGE, GET_ANALYTICS_PRIVILEGE, SEARCH_PRIVILEGE))
VIEW_ANALYTICS_PRIVILEGE,
GET_ANALYTICS_PRIVILEGE,
SEARCH_PRIVILEGE,
MANAGE_SYSTEM_OPERATIONS_PRIVILEGE))
.build())
.put(
ApiGroup.TIMESERIES,
Expand Down

0 comments on commit 5ad15a7

Please sign in to comment.