Skip to content

Commit

Permalink
Update docs on privilege elevation
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Aug 10, 2023
1 parent 683a169 commit 856104e
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 8 deletions.
68 changes: 60 additions & 8 deletions docs/expressions/expressions/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -537,31 +537,83 @@ Therefore the following two expressions are equivalent (assuming that user is se

== Security

=== Run As
[#_privilege_elevation]
=== Privilege Elevation (Run As, Run Privileged)

Expressions are normally evaluated using the security principal of the user that initiated the operation.
This is best security practice as the authorizations go deep into the system and close to the data.
In this it unlikely that an expression would read data or initiate an operation that the user is not authorized for.
Therefore the probability of a security breach is reduced.
This is the best security practice, as the authorizations go deep into the system and close to the data.
By doing this, it is unlikely that an expression would read data or initiate an operation that the user is not authorized for.
Therefore, the probability of a security breach is reduced.

However, there are some cases when an expression needs access to data or operations that the use do not usually has.
Since midPoint 3.6 the expression can be executed with the identity of a different user:
However, there are some cases when an expression needs access to data or operations beyond the user's authorization.
Since midPoint 3.6, the expression can be executed with the identity of a different user, and since 4.8, a faster option of elevating the privileges only is available as well.

==== How to Use Elevated Privileges
++++
{% include since.html since="4.8" %}
++++

The following example shows both options for privilege elevation.
Although they can be used at the same time, you normally use only one of them.

.An example of the current runAs/runPrivileged syntax
[source,xml]
----
<expression>
<runAsRef oid="e5e0f2fe-0aea-11e7-b02b-2b6815aa719e"/>
<privileges>
<runAsRef oid="e5e0f2fe-0aea-11e7-b02b-2b6815aa719e" type="UserType"/> <!--1-->
<runPrivileged>true</runPrivileged> <!--2-->
</privileges>
<script>
....
</script>
</expression>
----
<1> Switches the identity of the principal
<2> Keeps the identity, elevates only the privileges

The expression above will be executed with authorizations of the user identified by OID `e5e0f2fe-0aea-11e7-b02b-2b6815aa719e`. If the expression executes any operations that are audited, then this identity will also be used for auditing.
==== Legacy Way of Privilege Escalation (from 3.6 to 4.7.x)

.An example of the legacy runAs syntax
[source,xml]
----
<expression>
<runAsRef oid="e5e0f2fe-0aea-11e7-b02b-2b6815aa719e"/> <!-- from 3.6 to 4.7 -->
<script>
....
</script>
</expression>
----

==== Effects of Privilege Escalation

When `runAsRef` is used, the expression will be executed with the authorization of the object referenced.
In the examples above, it will be the user identified by OID `e5e0f2fe-0aea-11e7-b02b-2b6815aa719e`.

The variable `actor` that is present in most expressions still refers to the identity of the user that initiated the operations.
This variable is not affected by the `runAs` configuration.

When `runPrivileged` is used (since 4.8), the expression will be executed under the identity of the currently logged-in users.
Their authorizations will be extended by including "allow all" (`http://midpoint.evolveum.com/xml/ns/public/security/authorization-3#all`) for the duration of expression evaluation.

==== Performance Implications

The use of `runAsRef` involves the login process, which can take considerable time.
In some cases, the time needed may be in the range of tens of milliseconds.
This may or may not be acceptable, e.g., for the evaluation of frequently used expressions.

The use of `runPrivileged` should be much faster.

==== Auditing

Since 4.8, each audit record contains the `effectivePrincipalRef` item that contains the reference to the identity under which the operation took place.
When `runAsRef` is used, the referenced identity is recorded.

Also, `effectivePrivilegesModification` property is there, indicating whether privileges were modified with regard to the original ones defined in the repository.
When `runPrivileged` is used, this property has a value of `fullElevation`.

Please see xref:/midpoint/reference/security/privilege-elevation.adoc[] for more information.

=== Security of Script Expressions

Script expressions are a code that runs inside midPoint servers.
Expand Down
79 changes: 79 additions & 0 deletions docs/security/privilege-elevation.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
= Privilege Elevation (runAsRef, runPrivileged)
:page-since: 4.8
:page-toc: top

== Introduction
Sometimes we need a given expression (e.g., in mappings) to run under elevated privileges and/or a specific principal.

== Implementation

.Listing 1: Example use
[source,xml]
----
<expression>
<privileges>
<runAsRef oid="..." type="UserType"/> <!--1-->
<runPrivileged>true</runPrivileged> <!--2-->
</privileges>
<script>
<code>
// here we could execute actions that require elevated privileges
... midpoint.getObject(...) ...
... midpoint.searchObjects(...) ...
</code>
</script>
</expression>
----
<1> Switches the identity of the principal
<2> Keeps the identity, elevates only the privileges

The `<runAsRef>` directive has been present since 3.6.
It works well but takes some time as it requires the login of the specified principal.
The new `<runPrivileged>` property is much faster: it simply adds `#all` authorization to the current principal.

Usually, either one of these should be used.
However, it is possible to use both: first, a specified principal is logged in, and then their privileges are elevated.

== Auditing

The audit event record was enhanced by the following information:

.New items in the audit event record
[%autowidth]
|===
| Item | Meaning

| `effectivePrincipalRef`
| The effective principal that was used to execute the action.
This is the subject whose authorizations were evaluated to determine whether the action is allowed or not.
Usually, it is the same as the initiator.
But, e.g., when `runAsRef` is used, the effective principal is the one specified by that directive.
| `effectivePrivilegesModification`
| Present if the effective privileges used to execute the operation differ or may differ from the regular (declared) privileges of the "effectivePrincipalRef".
This is usually the case, e.g., when "runPrivileged" mechanism is used for expression evaluation.
|===

.Values for `effectivePrivilegesModification` property
[%autowidth]
|===
| Value | Meaning

| `elevation`
| Privileges were elevated to some degree.
It may or may not be the maximum degree (full authorization).
Only if we are really sure, the "fullElevation" value is set.

| `fullElevation`
| Privileges were elevated to the maximum degree, i.e. to full authorization.

| `reduction`
| Privileges were reduced to some degree.

| `other`
| Privileges were changed in a different way (maybe some reduced, others elevated).
|===

== See Also

- xref:/midpoint/reference/expressions/expressions/index.adoc#_privilege_elevation[]
- commits https://github.com/Evolveum/midpoint/commit/aab21f14d2da4798d21ec5af5f82e992aaafac2f[aab21f], https://github.com/Evolveum/midpoint/commit/ce357da80a1765eb64b23479470045dad53d0bef[ce357d], and https://github.com/Evolveum/midpoint/commit/a512e69f48467c389766c0f30ec06e790b787cbc[a512e6]

0 comments on commit 856104e

Please sign in to comment.