-
Notifications
You must be signed in to change notification settings - Fork 531
RoleAccess auditing/history functionality #11612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
253a034
a7f4b61
bf0beed
47e9805
1d3a111
2fbde58
9da8ee9
fe1f3e7
a1d5c8a
52e1877
8b93f30
d16eb77
c622259
334d8e0
04ac9ba
c7251f5
614697b
d896af5
06042f3
1bb5fe2
e687a87
1864d0d
65dc679
c87220e
cb57117
04b37f2
b6b86ea
d3ab76b
af6600f
4fca21b
8c0bfbf
859d0ab
1c87cef
a6a1ab1
c2c54dc
b1b4503
0989e35
db6e94b
478084a
7e468f4
13ac931
7ed23bf
94235c7
aad80c4
233f3e4
c0897a9
59c0680
eda9fe8
c167307
f10dcbb
0803726
715badb
baf5e18
696f009
ec2042d
dfba6a7
bc97830
fd4983c
94f4ff2
ceaf855
8ad46ff
77972b2
a348b98
6b2b76f
a1a85b4
06453fc
71a6e4e
c7c7e70
62f976e
8e12e43
bd2ab9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Role Assignment History Tracking | ||
|
|
||
| Dataverse can now track the history of role assignments, allowing administrators to see who assigned or revoked roles, when these actions occurred, and which roles were involved. This feature helps with auditing and understanding permission changes over time. | ||
|
|
||
| ## Key components of this feature: | ||
|
|
||
| - **Feature Flag**: The functionality can be enabled/disabled via the `ROLE_ASSIGNMENT_HISTORY` feature flag (default is `off`) | ||
| - **UI Integration**: New history panels on permission management pages showing the complete history of role assignments/revocations | ||
| - **CSV Export**: Administrators can download the role assignment history for a given collection or dataset (or files in a dataset) as a CSV file directly from the new panels | ||
| - **API Access**: New API endpoints provide access to role assignment history in both JSON and CSV formats: | ||
| - `/api/dataverses/{identifier}/assignments/history` | ||
| - `/api/datasets/{identifier}/assignments/history` | ||
| - `/api/datasets/{identifier}/files/assignments/history` | ||
|
|
||
| All return JSON by default but will return an internationalized CSV if an `Accept: text/csv` header is adde | ||
|
|
||
| For more information, see #11612 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1485,6 +1485,78 @@ The fully expanded example above (without environment variables) looks like this | |
|
|
||
| curl -H "X-Dataverse-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X POST "https://demo.dataverse.org/api/dataverses/1/templates" --upload-file dataverse-template.json | ||
|
|
||
|
|
||
| Dataverse Role Assignment History | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Get the history of role assignments for a collection. This API call returns a list of role assignments and revocations for the specified dataset. | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export ID=1 | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/dataverses/$ID/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/dataverses/3/assignments/history" | ||
|
|
||
| You can also use the collection alias instead of the numeric id: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export DV_ALIAS=dvAlias | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/dataverses/$DV_ALIAS/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/dvAlias/assignments/history" | ||
|
|
||
| The response is a JSON array of role assignment history entries with the following structure for each entry: | ||
|
|
||
| .. code-block:: json | ||
|
|
||
| { | ||
| "definedOn": "1", | ||
| "assigneeIdentifier": "@user1", | ||
| "roleName": "Admin", | ||
| "assignedBy": "@dataverseAdmin", | ||
| "assignedAt": "2023-01-01T12:00:00Z", | ||
| "revokedBy": null, | ||
| "revokedAt": null | ||
| } | ||
|
|
||
| For revoked assignments, the "revokedBy" and "revokedAt" fields will contain values instead of null. | ||
|
|
||
| To retrieve the history in CSV format, change the Accept header to "text/csv": | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export ID=3 | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: text/csv" "$SERVER_URL/api/dataverses/$ID/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: text/csv" "https://demo.dataverse.org/api/dataverses/3/assignments/history" | ||
|
|
||
| The CSV response has column headers mirroring the JSON entries. They are internationalized (when internationalization is configured). | ||
|
|
||
| Note: This feature requires the "role-assignment-history" feature flag to be enabled (see :ref:`feature-flags`). | ||
|
|
||
| Datasets | ||
| -------- | ||
|
|
||
|
|
@@ -4115,6 +4187,135 @@ Upon success, the API will return a JSON response with a success message and the | |
| The API call will report a 400 (BAD REQUEST) error if any of the files specified do not exist or are not in the latest version of the specified dataset. | ||
| The ``fileIds`` in the JSON payload should be an array of file IDs that you want to delete from the dataset. | ||
|
|
||
| .. _api-dataset-role-assignment-history: | ||
|
|
||
| Dataset Role Assignment History | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Get the history of role assignments for a dataset. This API call returns a list of role assignments and revocations for the specified dataset. | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export ID=3 | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/$ID/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/3/assignments/history" | ||
|
|
||
| You can also use the persistent identifier instead of the numeric id: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export PERSISTENT_IDENTIFIER=doi:10.5072/FK2/ABCDEF | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/:persistentId/assignments/history?persistentId=$PERSISTENT_IDENTIFIER" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/:persistentId/assignments/history?persistentId=doi:10.5072/FK2/ABCDEF" | ||
|
|
||
| The response is a JSON array of role assignment history entries with the following structure for each entry: | ||
|
|
||
| .. code-block:: json | ||
|
|
||
| { | ||
| "definedOn": "3", | ||
| "assigneeIdentifier": "@user1", | ||
| "roleName": "Admin", | ||
| "assignedBy": "@dataverseAdmin", | ||
| "assignedAt": "2023-01-01T12:00:00Z", | ||
| "revokedBy": null, | ||
| "revokedAt": null | ||
| } | ||
|
|
||
| For revoked assignments, the "revokedBy" and "revokedAt" fields will contain values instead of null. | ||
|
|
||
| To retrieve the history in CSV format, change the Accept header to "text/csv": | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export ID=3 | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: text/csv" "$SERVER_URL/api/datasets/$ID/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: text/csv" "https://demo.dataverse.org/api/datasets/3/assignments/history" | ||
|
|
||
| The CSV response has column headers mirroring the JSON entries. They are internationalized (when internationalization is configured). | ||
|
|
||
| Note: This feature requires the "role-assignment-history" feature flag to be enabled (see :ref:`feature-flags`). | ||
|
|
||
| Dataset Files Role Assignment History | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Get the history of role assignments for the files in a dataset. This API call returns a list of role assignments and revocations for all files in the specified dataset. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't show file requests, right? That's what this issue is about:
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right - this is just when assignments have been made or revoked. Whether a request is granted/denied is related but separate (denied would not have any RA history entries). |
||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export ID=3 | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/$ID/files/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/3/files/assignments/history" | ||
|
|
||
| You can also use the persistent identifier instead of the numeric id: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export PERSISTENT_IDENTIFIER=doi:10.5072/FK2/ABCDEF | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: application/json" "$SERVER_URL/api/datasets/:persistentId/files/assignments/history?persistentId=$PERSISTENT_IDENTIFIER" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: application/json" "https://demo.dataverse.org/api/datasets/:persistentId/files/assignments/history?persistentId=doi:10.5072/FK2/ABCDEF" | ||
|
|
||
| The JSON response for this call is the same as for the /api/datasets/{id}/assignments/history call above with the exception that definedOn will be a comma separated list of one or more file ids. | ||
|
|
||
| To retrieve the history in CSV format, change the Accept header to "text/csv": | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | ||
| export SERVER_URL=https://demo.dataverse.org | ||
| export ID=3 | ||
|
|
||
| curl -H "X-Dataverse-key:$API_TOKEN" -H "Accept: text/csv" "$SERVER_URL/api/datasets/files/$ID/assignments/history" | ||
|
|
||
| The fully expanded example above (without environment variables) looks like this: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -H "Accept: text/csv" "https://demo.dataverse.org/api/datasets/3/files/assignments/history" | ||
|
|
||
| The CSV response for this call is the same as for the /api/datasets/{id}/assignments/history call above with the exception that definedOn will be a comma separated list of one or more file ids. | ||
|
|
||
| Note: This feature requires the "role-assignment-history" feature flag to be enabled (see :ref:`feature-flags`). | ||
|
|
||
| Files | ||
| ----- | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -119,14 +119,16 @@ Clicking on Permissions will bring you to this page: | |
|
|
||
| |image3| | ||
|
|
||
| When you access a Dataverse collection's permissions page, you will see three sections: | ||
| When you access a Dataverse collection's permissions page, you will see three or four sections: | ||
|
|
||
| **Permissions:** Here you can decide the requirements that determine which types of users can add datasets and sub Dataverse collections to your Dataverse collection, and what permissions they'll be granted when they do so. | ||
|
|
||
| **Users/Groups:** Here you can assign roles to specific users or groups, determining which actions they are permitted to take on your Dataverse collection. You can also reference a list of all users who have roles assigned to them for your Dataverse collection and remove their roles if you please. | ||
|
|
||
| **Roles:** Here you can reference a full list of roles that can be assigned to users of your Dataverse collection. Each role lists the permissions that it offers. | ||
|
|
||
| **Role Assignment History** If enabled, you'll be able to see the history of when roles have been assigned and revoked and by whom. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we link to the feature flag here? |
||
|
|
||
| Please note that even on a newly created Dataverse collection, you may see user and groups have already been granted role(s) if your installation has ``:InheritParentRoleAssignments`` set. For more on this setting, see the :doc:`/installation/config` section of the Installation Guide. | ||
|
|
||
| Setting Access Configurations | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elsewhere we have both
definitionPointIdanddefinitionPointName:Should we consider showing both instead of just the id?
At the very least, should we consider switching to
definitionPointId, for consistency? It appears above and in the following JsonPrinter method:Obviously, internal consistency across the JSON and CSV formats for this feature is desired, as well, so we should update both if we make any updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure - 'both' only exist for dataverses (id, alias) whereas datasets/files could use (id, PID (if available)), and the file-level call can actually return a comma-separated list of file ids in the definedOn field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Maybe we can revisit this when we build this feature in the SPA. Or maybe we won't have to. 🤷