Browse Source

YAML tests and docs for viewing API key role descriptors (#89186)

This PR expands existing YAML tests and docs for the new
role_descriptors field returned in both Get and Query API key calls.

Relates: #89166, #89058
Yang Wang 3 năm trước cách đây
mục cha
commit
2841bf7646

+ 36 - 2
x-pack/docs/en/rest-api/security/get-api-keys.asciidoc

@@ -15,7 +15,11 @@ Retrieves information for one or more API keys.
 [[security-api-get-api-key-prereqs]]
 ==== {api-prereq-title}
 
-* To use this API, you must have at least the `manage_api_key` cluster privilege.
+* To use this API, you must have at least the `manage_own_api_key` cluster privilege.
+* If you have only the `manage_own_api_key` privilege, this API returns only
+the API keys that you own. If you have the `manage_api_key` or greater
+privileges (including `manage_security`), this API returns all API keys
+regardless of ownership.
 
 [[security-api-get-api-key-desc]]
 ==== {api-description-title}
@@ -190,6 +194,30 @@ A successful call returns a JSON structure that contains the information of one
       "realm": "native1", <8>
       "metadata": { <9>
         "application": "myapp"
+      },
+      "role_descriptors": { <10>
+        "role-a": {
+          "cluster": [
+            "monitor"
+          ],
+          "indices": [
+            {
+              "names": [
+                "index-a"
+              ],
+              "privileges": [
+                "read"
+              ],
+              "allow_restricted_indices": false
+            }
+          ],
+          "applications": [ ],
+          "run_as": [ ],
+          "metadata": { },
+          "transient_metadata": {
+            "enabled": true
+          }
+        }
       }
     },
     {
@@ -199,7 +227,8 @@ A successful call returns a JSON structure that contains the information of one
       "invalidated": false,
       "username": "user-y",
       "realm": "realm-2",
-      "metadata": {}
+      "metadata": {},
+      "role_descriptors": { } <11>
     }
   ]
 }
@@ -216,3 +245,8 @@ a value of `true`. Otherwise, it is `false`.
 <7> Principal for which this API key was created
 <8> Realm name of the principal for which this API key was created
 <9> Metadata of the API key
+<10> The role descriptors assigned to this API key when it was <<api-key-role-descriptors,created>>
+or last <<security-api-update-api-key-api-key-role-descriptors,updated>>. The API key's
+effective permissions are an intersection of its assigned privileges and the point-in-time snapshot of
+the owner user's permissions.
+<11> An empty role descriptor means the API key inherits the owner user's permissions.

+ 36 - 3
x-pack/docs/en/rest-api/security/query-api-key.asciidoc

@@ -46,8 +46,7 @@ The query supports a subset of query types, including
 <<query-dsl-prefix-query,`prefix`>>, <<query-dsl-wildcard-query,`wildcard`>>, <<query-dsl-exists-query,`exists`>>,
 and <<query-dsl-range-query,`range`>>.
 +
-You can query all public information associated with an API key, including the
-following values.
+You can query the following public values associated with an API key.
 +
 .Valid values for `query`
 [%collapsible%open]
@@ -78,6 +77,8 @@ Realm name of the API key owner.
 Metadata field associated with the API key, such as `metadata.my_field`. Because
 metadata is stored as a <<flattened,flattened>> field type, all fields act like
 `keyword` fields when querying and sorting.
+
+NOTE: You cannot query the role descriptors of an API key.
 ====
 
 include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=from]
@@ -146,6 +147,30 @@ retrieved from one or more API keys:
       "realm": "reserved",
       "metadata": {
         "letter": "a"
+      },
+      "role_descriptors": { <2>
+        "role-a": {
+          "cluster": [
+            "monitor"
+          ],
+          "indices": [
+            {
+              "names": [
+                "index-a"
+              ],
+              "privileges": [
+                "read"
+              ],
+              "allow_restricted_indices": false
+            }
+          ],
+          "applications": [ ],
+          "run_as": [ ],
+          "metadata": { },
+          "transient_metadata": {
+            "enabled": true
+          }
+        }
       }
     },
     {
@@ -158,7 +183,8 @@ retrieved from one or more API keys:
       "realm": "reserved",
       "metadata": {
         "letter": "b"
-      }
+      },
+      "role_descriptors": { } <3>
     }
   ]
 }
@@ -166,6 +192,11 @@ retrieved from one or more API keys:
 // NOTCONSOLE
 
 <1> The list of API keys that were retrieved for this request
+<2> The role descriptors that are assigned to this API key when it was <<api-key-role-descriptors,created>>
+or last <<security-api-update-api-key-api-key-role-descriptors,updated>>. Note the API key's
+effective permissions are an intersection of its assigned privileges and the point-in-time snapshot of
+the owner user's permissions.
+<3> An empty role descriptors means the API key inherits the owner user's permissions.
 
 If you create an API key with the following details:
 
@@ -308,6 +339,7 @@ The response contains a list of matched API keys along with their sort values:
       "metadata": {
         "environment": "production"
       },
+      "role_descriptors": { },
       "_sort": [
         "2021-08-18T01:29:14.811Z",  <1>
         "app1-key-79"  <2>
@@ -323,6 +355,7 @@ The response contains a list of matched API keys along with their sort values:
       "metadata": {
         "environment": "production"
       },
+      "role_descriptors": { },
       "_sort": [
         "2021-08-18T01:29:13.794Z",
         "app1-key-78"

+ 332 - 0
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/40_view_role_descriptors.yml

@@ -0,0 +1,332 @@
+---
+setup:
+  - skip:
+      features: headers
+
+  - do:
+      cluster.health:
+          wait_for_status: yellow
+
+  - do:
+      security.put_role:
+        name: "admin_role"
+        body:  >
+            {
+              "cluster": ["manage_api_key"],
+              "indices": [
+                {
+                  "names": "*",
+                  "privileges": ["all"]
+                }
+              ],
+              "applications": [
+                {
+                  "application": "myapp",
+                  "privileges": ["*"],
+                  "resources": ["*"]
+                }
+              ]
+            }
+
+  - do:
+      security.put_user:
+        username: "api_key_user"
+        body:  >
+          {
+            "password" : "x-pack-test-password",
+            "roles" : [ "admin_role" ],
+            "full_name" : "API key user"
+          }
+
+
+
+---
+teardown:
+  - do:
+      security.delete_role:
+        name: "admin_role"
+        ignore: 404
+
+  - do:
+      security.delete_user:
+        username: "api_key_user"
+        ignore: 404
+
+---
+"Test API key role descriptors in Get and Query responses":
+  - skip:
+      features: transform_and_set
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.create_api_key:
+        body:  >
+          {
+            "name": "key-0-with-implicit-inherit"
+          }
+  - match: { name: "key-0-with-implicit-inherit" }
+  - is_true: id
+  - set: { id: api_key_id_0 }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.get_api_key:
+        id: "$api_key_id_0"
+  - match: { "api_keys.0.id": "$api_key_id_0" }
+  - match: { "api_keys.0.role_descriptors": { } }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.create_api_key:
+        body:  >
+          {
+            "name": "key-1-with-explicit-inherit",
+            "role_descriptors": {}
+          }
+  - match: { name: "key-1-with-explicit-inherit" }
+  - is_true: id
+  - set: { id: api_key_id_1 }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.get_api_key:
+        id: "$api_key_id_1"
+  - match: { "api_keys.0.id": "$api_key_id_1" }
+  - match: { "api_keys.0.role_descriptors": { } }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.create_api_key:
+        body:  >
+          {
+            "name": "key-2-with-single-assigned-role-descriptor",
+            "role_descriptors": {
+              "role-a": {
+                "cluster": ["all"],
+                "index": [
+                  {
+                    "names": ["index-a"],
+                    "privileges": ["read"]
+                  }
+                ]
+              }
+            }
+          }
+  - match: { name: "key-2-with-single-assigned-role-descriptor" }
+  - is_true: id
+  - set: { id: api_key_id_2 }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.get_api_key:
+        id: "$api_key_id_2"
+  - match: { "api_keys.0.id": "$api_key_id_2" }
+  - match: { "api_keys.0.role_descriptors": {
+    "role-a": {
+      "cluster": [
+        "all"
+      ],
+      "indices": [
+        {
+          "names": [
+            "index-a"
+          ],
+          "privileges": [
+            "read"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [ ],
+      "run_as": [ ],
+      "metadata": { },
+      "transient_metadata": {
+        "enabled": true
+      }
+    }
+  }
+  }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.create_api_key:
+        body:  >
+          {
+            "name": "key-3-with-multiple-assigned-role-descriptors",
+            "expiration": "1d",
+            "role_descriptors": {
+              "role-a": {
+                "cluster": ["all"],
+                "index": [
+                  {
+                    "names": ["index-a"],
+                    "privileges": ["read"]
+                  }
+                ]
+              },
+              "role-b": {
+                "cluster": ["manage"],
+                "index": [
+                  {
+                    "names": ["index-b"],
+                    "privileges": ["all"]
+                  }
+                ]
+              }
+            }
+          }
+  - match: { name: "key-3-with-multiple-assigned-role-descriptors" }
+  - is_true: id
+  - set: { id: api_key_id_3 }
+
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.get_api_key:
+        id: "$api_key_id_3"
+  - match: { "api_keys.0.id": "$api_key_id_3" }
+  - match: { "api_keys.0.role_descriptors": {
+    "role-a": {
+      "cluster": [
+        "all"
+      ],
+      "indices": [
+        {
+          "names": [
+            "index-a"
+          ],
+          "privileges": [
+            "read"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [ ],
+      "run_as": [ ],
+      "metadata": { },
+      "transient_metadata": {
+        "enabled": true
+      }
+    },
+    "role-b": {
+      "cluster": [
+        "manage"
+      ],
+      "indices": [
+        {
+          "names": [
+            "index-b"
+          ],
+          "privileges": [
+            "all"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [ ],
+      "run_as": [ ],
+      "metadata": { },
+      "transient_metadata": {
+        "enabled": true
+      }
+    }
+  }
+  }
+
+  # Query API keys
+  - do:
+      headers:
+        Authorization: "Basic YXBpX2tleV91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" # api_key_user
+      security.query_api_keys:
+        body: >
+          {
+            "sort": [ "name" ]
+          }
+  - match: { total: 4 }
+  - match: { count: 4 }
+  - match: { "api_keys.0.name": "key-0-with-implicit-inherit" }
+  - match: { "api_keys.0.role_descriptors": { } }
+  - match: { "api_keys.1.name": "key-1-with-explicit-inherit" }
+  - match: { "api_keys.1.role_descriptors": { } }
+  - match: { "api_keys.2.name": "key-2-with-single-assigned-role-descriptor"}
+  - match: { "api_keys.2.role_descriptors": {
+    "role-a": {
+      "cluster": [
+        "all"
+      ],
+      "indices": [
+        {
+          "names": [
+            "index-a"
+          ],
+          "privileges": [
+            "read"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [ ],
+      "run_as": [ ],
+      "metadata": { },
+      "transient_metadata": {
+        "enabled": true
+      }
+    }
+  }
+  }
+  - match: { "api_keys.3.name": "key-3-with-multiple-assigned-role-descriptors"}
+  - match: { "api_keys.3.role_descriptors": {
+    "role-a": {
+      "cluster": [
+        "all"
+      ],
+      "indices": [
+        {
+          "names": [
+            "index-a"
+          ],
+          "privileges": [
+            "read"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [ ],
+      "run_as": [ ],
+      "metadata": { },
+      "transient_metadata": {
+        "enabled": true
+      }
+    },
+    "role-b": {
+      "cluster": [
+        "manage"
+      ],
+      "indices": [
+        {
+          "names": [
+            "index-b"
+          ],
+          "privileges": [
+            "all"
+          ],
+          "allow_restricted_indices": false
+        }
+      ],
+      "applications": [ ],
+      "run_as": [ ],
+      "metadata": { },
+      "transient_metadata": {
+        "enabled": true
+      }
+    }
+  }
+  }
+