Open peternied opened 1 year ago
@peternied, @RyanL1997, @DarshitChanpura, and @cwperks, do you have any thoughts about the permission formatting requirements?
I am thinking of two options. We could make it so that you can do basically anything as a valid permission as long as it had the correct deliminator usage and then leave the real checking to the step where we are going to check that the permission matches the required permission. Or we could implement a way of making sure that the permissions are constrained to real permission items using a list of keywords etc. My one concern with the latter is that we would then offer fewer configuration options since if anyone wanted to modify the naming conventions of the permissions for some reason (maybe they wanted their logs to say mycluster.myindex.read
they would need to be able to add things to the list of permission keywords. The first option does not require this but will either combine the matching check into part of the formatting check or duplicate the effort (yuck).
What does everyone think? I am leaning towards the second option but maybe there is another way of doing things I am overlooking.
EDIT: Can someone give me access to the Identity Project Board? I cannot assign this to myself for whatever reason even though I can drag the columns around and type in the expected days etc. Thank you!
Jotting down some initial thoughts.
Action/Permissions should be broken down into 3 major categories:
cluster
indices
plugin
/ extension
For index permissions, I like to draw analogies to SQL though there may not always be a 1-to-1 comparison
SQL Syntax: GRANT <permission> TO <database_principal > ON <table>
.
database_principal
in this case can be a role or a user
ActionName | Handler | Category | Group(s) | Identity Permission |
---|---|---|---|---|
indices:admin/mapping/put | org.opensearch.action.admin.indices.mapping.put.TransportPutMappingAction | indices | ||
indices:admin/resolve/index | org.opensearch.action.admin.indices.resolve.ResolveIndexAction$TransportAction | indices | ||
cluster:admin/script_language/get | org.opensearch.action.admin.cluster.storedscripts.TransportGetScriptLanguageAction | cluster | ||
cluster:monitor/tasks/lists | org.opensearch.action.admin.cluster.node.tasks.list.TransportListTasksAction | cluster | ||
cluster:admin/component_template/delete | org.opensearch.action.admin.indices.template.delete.TransportDeleteComponentTemplateAction | cluster | ||
indices:admin/flush | org.opensearch.action.admin.indices.flush.TransportFlushAction | indices | ||
indices:admin/data_stream/delete | org.opensearch.action.admin.indices.datastream.DeleteDataStreamAction$TransportAction | indices | ||
indices:data/read/explain | org.opensearch.action.explain.TransportExplainAction | indices | ||
internal:indices/admin/upgrade | org.opensearch.action.admin.indices.upgrade.post.TransportUpgradeSettingsAction | internal | ||
cluster:admin/script_context/get | org.opensearch.action.admin.cluster.storedscripts.TransportGetScriptContextAction | cluster | ||
indices:admin/auto_create | org.opensearch.action.admin.indices.create.AutoCreateAction$TransportAction | indices | ||
indices:monitor/shard_stores | org.opensearch.action.admin.indices.shards.TransportIndicesShardStoresAction | indices | ||
cluster:monitor/remote/info | org.opensearch.action.admin.cluster.remote.TransportRemoteInfoAction | cluster | ||
cluster:admin/snapshot/delete | org.opensearch.action.admin.cluster.snapshots.delete.TransportDeleteSnapshotAction | cluster | ||
indices:data/write/update | org.opensearch.action.update.TransportUpdateAction | indices | ||
indices:admin/data_stream/get | org.opensearch.action.admin.indices.datastream.GetDataStreamAction$TransportAction | indices | ||
indices:admin/settings/update | org.opensearch.action.admin.indices.settings.put.TransportUpdateSettingsAction | indices | ||
indices:admin/close | org.opensearch.action.admin.indices.close.TransportCloseIndexAction | indices | ||
indices:admin/refresh | org.opensearch.action.admin.indices.refresh.TransportRefreshAction | indices | ||
cluster:admin/ingest/pipeline/simulate | org.opensearch.action.ingest.SimulatePipelineTransportAction | cluster | ||
indices:admin/mappings/get | org.opensearch.action.admin.indices.mapping.get.TransportGetMappingsAction | indices | ||
cluster:admin/snapshot/create | org.opensearch.action.admin.cluster.snapshots.create.TransportCreateSnapshotAction | cluster | ||
cluster:monitor/stats | org.opensearch.action.admin.cluster.stats.TransportClusterStatsAction | cluster | ||
cluster:admin/reroute | org.opensearch.action.admin.cluster.reroute.TransportClusterRerouteAction | cluster | ||
cluster:monitor/nodes/info | org.opensearch.action.admin.cluster.node.info.TransportNodesInfoAction | cluster | ||
indices:monitor/recovery | org.opensearch.action.admin.indices.recovery.TransportRecoveryAction | indices | ||
indices:admin/shards/search_shards | org.opensearch.action.admin.cluster.shards.TransportClusterSearchShardsAction | indices | ||
indices:monitor/data_stream/stats | org.opensearch.action.admin.indices.datastream.DataStreamsStatsAction$TransportAction | indices | ||
cluster:admin/snapshot/get | org.opensearch.action.admin.cluster.snapshots.get.TransportGetSnapshotsAction | cluster | ||
cluster:admin/component_template/put | org.opensearch.action.admin.indices.template.put.TransportPutComponentTemplateAction | cluster | ||
indices:admin/index_template/simulate | org.opensearch.action.admin.indices.template.post.TransportSimulateTemplateAction | indices | ||
cluster:admin/decommission/awareness/get | org.opensearch.action.admin.cluster.decommission.awareness.get.TransportGetDecommissionStateAction | cluster | ||
cluster:admin/routing/awareness/weights/get | org.opensearch.action.admin.cluster.shards.routing.weighted.get.TransportGetWeightedRoutingAction | cluster | ||
indices:admin/block/add | org.opensearch.action.admin.indices.readonly.TransportAddIndexBlockAction | indices | ||
indices:admin/template/delete | org.opensearch.action.admin.indices.template.delete.TransportDeleteIndexTemplateAction | indices | ||
indices:admin/index_template/get | org.opensearch.action.admin.indices.template.get.TransportGetComposableIndexTemplateAction | indices | ||
indices:admin/mapping/auto_put | org.opensearch.action.admin.indices.mapping.put.TransportAutoPutMappingAction | indices | ||
indices:data/read/search | org.opensearch.action.search.TransportSearchAction | indices | ||
cluster:admin/ingest/pipeline/delete | org.opensearch.action.ingest.DeletePipelineTransportAction | cluster | ||
indices:admin/create | org.opensearch.action.admin.indices.create.TransportCreateIndexAction | indices | ||
indices:admin/seq_no/add_retention_lease | org.opensearch.index.seqno.RetentionLeaseActions$Add$TransportAction | indices | ||
cluster:admin/repository/verify | org.opensearch.action.admin.cluster.repositories.verify.TransportVerifyRepositoryAction | cluster | ||
indices:admin/forcemerge | org.opensearch.action.admin.indices.forcemerge.TransportForceMergeAction | indices | ||
indices:admin/template/put | org.opensearch.action.admin.indices.template.put.TransportPutIndexTemplateAction | indices | ||
indices:data/read/field_caps | org.opensearch.action.fieldcaps.TransportFieldCapabilitiesAction[class org.opensearch.action.fieldcaps.TransportFieldCapabilitiesIndexAction] | indices | ||
cluster:admin/decommission/awareness/delete | org.opensearch.action.admin.cluster.decommission.awareness.delete.TransportDeleteDecommissionStateAction | cluster | ||
indices:admin/seq_no/remove_retention_lease | org.opensearch.index.seqno.RetentionLeaseActions$Remove$TransportAction | indices | ||
indices:monitor/upgrade | org.opensearch.action.admin.indices.upgrade.get.TransportUpgradeStatusAction | indices | ||
indices:admin/seq_no/renew_retention_lease | org.opensearch.index.seqno.RetentionLeaseActions$Renew$TransportAction | indices | ||
cluster:admin/remotestore/restore | org.opensearch.action.admin.cluster.remotestore.restore.TransportRestoreRemoteStoreAction | cluster | ||
cluster:monitor/task/get | org.opensearch.action.admin.cluster.node.tasks.get.TransportGetTaskAction | cluster | ||
indices:admin/rollover | org.opensearch.action.admin.indices.rollover.TransportRolloverAction | indices | ||
cluster:monitor/state | org.opensearch.action.admin.cluster.state.TransportClusterStateAction | cluster | ||
indices:data/write/delete | org.opensearch.action.delete.TransportDeleteAction | indices | ||
indices:data/read/scroll | org.opensearch.action.search.TransportSearchScrollAction | indices | ||
indices:admin/index_template/delete | org.opensearch.action.admin.indices.template.delete.TransportDeleteComposableIndexTemplateAction | indices | ||
cluster:admin/voting_config/add_exclusions | org.opensearch.action.admin.cluster.configuration.TransportAddVotingConfigExclusionsAction | cluster | ||
indices:admin/cache/clear | org.opensearch.action.admin.indices.cache.clear.TransportClearIndicesCacheAction | indices | ||
indices:data/write/bulk | org.opensearch.action.bulk.TransportBulkAction[class org.opensearch.action.bulk.TransportShardBulkAction] | indices | ||
indices:admin/mappings/fields/get | org.opensearch.action.admin.indices.mapping.get.TransportGetFieldMappingsAction[class org.opensearch.action.admin.indices.mapping.get.TransportGetFieldMappingsIndexAction] | indices | ||
indices:admin/open | org.opensearch.action.admin.indices.open.TransportOpenIndexAction | indices | ||
cluster:admin/script/delete | org.opensearch.action.admin.cluster.storedscripts.TransportDeleteStoredScriptAction | cluster | ||
indices:admin/analyze | org.opensearch.action.admin.indices.analyze.TransportAnalyzeAction | indices | ||
cluster:admin/decommission/awareness/put | org.opensearch.action.admin.cluster.decommission.awareness.put.TransportDecommissionAction | cluster | ||
cluster:admin/persistent/start | org.opensearch.persistent.StartPersistentTaskAction$TransportAction | cluster | ||
indices:data/read/mget | org.opensearch.action.get.TransportMultiGetAction[class org.opensearch.action.get.TransportShardMultiGetAction] | indices | ||
cluster:admin/routing/awareness/weights/put | org.opensearch.action.admin.cluster.shards.routing.weighted.put.TransportAddWeightedRoutingAction | cluster | ||
cluster:admin/repository/delete | org.opensearch.action.admin.cluster.repositories.delete.TransportDeleteRepositoryAction | cluster | ||
indices:data/read/point_in_time/create | org.opensearch.action.search.TransportCreatePitAction | indices | ||
cluster:admin/tasks/cancel | org.opensearch.action.admin.cluster.node.tasks.cancel.TransportCancelTasksAction | cluster | ||
cluster:admin/persistent/completion | org.opensearch.persistent.CompletionPersistentTaskAction$TransportAction | cluster | ||
cluster:admin/snapshot/clone | org.opensearch.action.admin.cluster.snapshots.clone.TransportCloneSnapshotAction | cluster | ||
indices:data/read/mtv | org.opensearch.action.termvectors.TransportMultiTermVectorsAction[class org.opensearch.action.termvectors.TransportShardMultiTermsVectorAction] | indices | ||
cluster:admin/script/put | org.opensearch.action.admin.cluster.storedscripts.TransportPutStoredScriptAction | cluster | ||
indices:admin/data_stream/create | org.opensearch.action.admin.indices.datastream.CreateDataStreamAction$TransportAction | indices | ||
indices:data/read/point_in_time/readall | org.opensearch.action.search.TransportGetAllPitsAction | indices | ||
indices:data/read/msearch | org.opensearch.action.search.TransportMultiSearchAction | indices | ||
cluster:monitor/nodes/hot_threads | org.opensearch.action.admin.cluster.node.hotthreads.TransportNodesHotThreadsAction | cluster | ||
cluster:monitor/health | org.opensearch.action.admin.cluster.health.TransportClusterHealthAction | cluster | ||
indices:admin/delete | org.opensearch.action.admin.indices.delete.TransportDeleteIndexAction | indices | ||
indices:data/read/tv | org.opensearch.action.termvectors.TransportTermVectorsAction | indices | ||
cluster:admin/voting_config/clear_exclusions | org.opensearch.action.admin.cluster.configuration.TransportClearVotingConfigExclusionsAction | cluster | ||
cluster:admin/routing/awareness/weights/delete | org.opensearch.action.admin.cluster.shards.routing.weighted.delete.TransportDeleteWeightedRoutingAction | cluster | ||
cluster:admin/indices/dangling/find | org.opensearch.action.admin.indices.dangling.find.TransportFindDanglingIndexAction | cluster | ||
cluster:monitor/task | org.opensearch.action.admin.cluster.tasks.TransportPendingClusterTasksAction | cluster | ||
cluster:admin/nodes/reload_secure_settings | org.opensearch.action.admin.cluster.node.reload.TransportNodesReloadSecureSettingsAction | cluster | ||
indices:monitor/point_in_time/segments | org.opensearch.action.admin.indices.segments.TransportPitSegmentsAction | indices | ||
indices:admin/template/get | org.opensearch.action.admin.indices.template.get.TransportGetIndexTemplatesAction | indices | ||
indices:admin/resize | org.opensearch.action.admin.indices.shrink.TransportResizeAction | indices | ||
indices:admin/exists | org.opensearch.action.admin.indices.exists.indices.TransportIndicesExistsAction | indices | ||
cluster:admin/repository/put | org.opensearch.action.admin.cluster.repositories.put.TransportPutRepositoryAction | cluster | ||
cluster:admin/ingest/pipeline/put | org.opensearch.action.ingest.PutPipelineTransportAction | cluster | ||
indices:monitor/stats | org.opensearch.action.admin.indices.stats.TransportIndicesStatsAction | indices | ||
cluster:admin/settings/update | org.opensearch.action.admin.cluster.settings.TransportClusterUpdateSettingsAction | cluster | ||
cluster:admin/persistent/remove | org.opensearch.persistent.RemovePersistentTaskAction$TransportAction | cluster | ||
cluster:admin/script/get | org.opensearch.action.admin.cluster.storedscripts.TransportGetStoredScriptAction | cluster | ||
indices:data/read/point_in_time/delete | org.opensearch.action.search.TransportDeletePitAction | indices | ||
indices:admin/validate/query | org.opensearch.action.admin.indices.validate.query.TransportValidateQueryAction | indices | ||
indices:monitor/segments | org.opensearch.action.admin.indices.segments.TransportIndicesSegmentsAction | indices | ||
cluster:admin/indices/dangling/list | org.opensearch.action.admin.indices.dangling.list.TransportListDanglingIndicesAction | cluster | ||
cluster:admin/snapshot/status | org.opensearch.action.admin.cluster.snapshots.status.TransportSnapshotsStatusAction | cluster | ||
indices:admin/index_template/simulate_index | org.opensearch.action.admin.indices.template.post.TransportSimulateIndexTemplateAction | indices | ||
indices:admin/aliases | org.opensearch.action.admin.indices.alias.TransportIndicesAliasesAction | indices | ||
cluster:admin/indices/dangling/import | org.opensearch.action.admin.indices.dangling.import_index.TransportImportDanglingIndexAction | cluster | ||
indices:monitor/settings/get | org.opensearch.action.admin.indices.settings.get.TransportGetSettingsAction | indices | ||
cluster:monitor/allocation/explain | org.opensearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction | cluster | ||
indices:admin/aliases/get | org.opensearch.action.admin.indices.alias.get.TransportGetAliasesAction | indices | ||
cluster:monitor/nodes/stats | org.opensearch.action.admin.cluster.node.stats.TransportNodesStatsAction | cluster | ||
cluster:admin/indices/dangling/delete | org.opensearch.action.admin.indices.dangling.delete.TransportDeleteDanglingIndexAction | cluster | ||
indices:data/read/scroll/clear | org.opensearch.action.search.TransportClearScrollAction | indices | ||
indices:admin/index_template/put | org.opensearch.action.admin.indices.template.put.TransportPutComposableIndexTemplateAction | indices | ||
cluster:admin/repository/get | org.opensearch.action.admin.cluster.repositories.get.TransportGetRepositoriesAction | cluster | ||
cluster:monitor/main | org.opensearch.action.main.TransportMainAction | cluster | ||
indices:admin/get | org.opensearch.action.admin.indices.get.TransportGetIndexAction | indices | ||
cluster:admin/ingest/pipeline/get | org.opensearch.action.ingest.GetPipelineTransportAction | cluster | ||
cluster:admin/persistent/update_status | org.opensearch.persistent.UpdatePersistentTaskStatusAction$TransportAction | cluster | ||
indices:admin/upgrade | org.opensearch.action.admin.indices.upgrade.post.TransportUpgradeAction | indices | ||
cluster:admin/repository/_cleanup | org.opensearch.action.admin.cluster.repositories.cleanup.TransportCleanupRepositoryAction | cluster | ||
cluster:admin/component_template/get | org.opensearch.action.admin.indices.template.get.TransportGetComponentTemplateAction | cluster | ||
indices:data/write/index | org.opensearch.action.index.TransportIndexAction | indices | ||
cluster:admin/snapshot/restore | org.opensearch.action.admin.cluster.snapshots.restore.TransportRestoreSnapshotAction | cluster | ||
indices:data/read/get | org.opensearch.action.get.TransportGetAction | indices | ||
cluster:monitor/nodes/usage | org.opensearch.action.admin.cluster.node.usage.TransportNodesUsageAction | cluster |
When thinking about a permissions naming convention, it will need to consider all of these actions and actions that are added to OpenSearch via plugins/extensions
One idea is to make the concept of an action group part of core so that in addition to an action requiring a name, it can also optionally define a list of groups. This could be statically defined in files like the security plugin or in the definition of the action itself. Here would be SearchAction for example:
public class SearchAction extends ActionType<SearchResponse> {
public static final SearchAction INSTANCE = new SearchAction();
public static final String NAME = "indices:data/read/search";
// Groups added here
public static final String GROUPS = List.of("read");
private SearchAction() {
super(NAME, SearchResponse::new);
}
}
the current permissions system supports wildcards to resolve the list of permissions that match indices:data/read/*
which I think the identity permission system should support as well.
Hi @cwperks, thank you for sharing this list. It is definitely helpful to see all the different actions we currently support when thinking about how to organize/name permissions in the new model. I think one of the major struggles with this is going to be condensing some of the permission names given the existing actions are so long.
As mentioned above, I had been thinking about something along the lines of
https://github.com/opensearch-project/OpenSearch/issues/5889 is tracking name schema / campaigns so you could defer some of this as long as the implementation was flexible with whatever constraints we pick
5889 is tracking name schema / campaigns so you could defer some of this as long as the implementation was flexible with whatever constraints we pick
That sounds good to me. Right now, I am awaiting some more design feedback and looking at how to generalize the exceptions and logging for the two interfaces. I also need to implement admin checks for the operations.
This is all done with #6154 except the part that prevents granting a permission to a non-existant principal. Right now, I am not sure how we do that without having the principals all be stored in the cluster. I had thought that this is something we had wanted to avoid. I am in favor of not worrying about whether a principal exists or not when a grant occurs. Perhaps we will need to add a TTL for permissions in storage to flush out unused permissions (make it LRU queue that runs alongside the mapping), but either way I think more discussion is needed before I can implement a principal validation mechanism.
Maybe we can consider this issue resolved and move the principal validation aspect to its own issue?
Use case:
There are actions that given a principle can create, retrieve, update, delete the permissions grants it has.
Acceptance Criteria:
opensearch.indexing.index.create, http-logs
allows for creating an index named http-logs