From 3f11c24c13fea19251fee71861224e6658ae6925 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 11 Jun 2024 08:39:54 +0100 Subject: [PATCH] VAULT-23335: Audit - Exclusion Docs (Draft) (#26696) * Added exclusion draft docs * added message to link exported types RequestEntry and ResponseEntry to website docs * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * `an` => `a` * quotes * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/docs/enterprise/audit/exclusion.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * Update website/content/partials/audit-options-common.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> * JSON {} 'objects' * condition is optional * Update website/content/docs/enterprise/audit/exclusion.mdx --------- Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> --- audit/types.go | 6 + .../docs/enterprise/audit/exclusion.mdx | 285 ++++++++++++ .../content/partials/audit-options-common.mdx | 6 + .../audit/request-entry-json-schema.mdx | 224 ++++++++++ .../audit/response-entry-json-schema.mdx | 418 ++++++++++++++++++ website/data/docs-nav-data.json | 4 + 6 files changed, 943 insertions(+) create mode 100644 website/content/docs/enterprise/audit/exclusion.mdx create mode 100644 website/content/partials/audit/request-entry-json-schema.mdx create mode 100644 website/content/partials/audit/response-entry-json-schema.mdx diff --git a/audit/types.go b/audit/types.go index 25652c7d03..9bebc57afa 100644 --- a/audit/types.go +++ b/audit/types.go @@ -7,6 +7,12 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) +// NOTE: Any exported changes made to RequestEntry, ResponseEntry or the structs +// used to compose them, must be reflected in the public facing documentation. +// See: /vault/docs/audit (website/content/docs/audit/index.mdx), which at the time +// of writing contains JSON examples and JSON schemas intended for use in audit +// exclusion. + // RequestEntry is the structure of a request audit log entry. type RequestEntry struct { Auth *Auth `json:"auth,omitempty"` diff --git a/website/content/docs/enterprise/audit/exclusion.mdx b/website/content/docs/enterprise/audit/exclusion.mdx new file mode 100644 index 0000000000..e6ebccec5b --- /dev/null +++ b/website/content/docs/enterprise/audit/exclusion.mdx @@ -0,0 +1,285 @@ +--- +layout: docs +page_title: Exclusion syntax for audit results +description: >- + Learn about the behavior and syntax for excluding audit data in Vault Enterprise. +--- + +# Exclusion syntax for audit results + +@include 'alerts/enterprise-only.mdx' + +As of Vault 1.18.0, you can enable audit devices with an `exclude` option to exclude +specific fields in an audit entry that is written to a particular audit log, and fine-tune +your auditing process. + + + + Excluding audit entry fields is an advanced feature. Use of exclusion settings + could lead to missing data in your audit logs. + + **Always** test your audit configuration in a non-production environment + before deploying exclusions to production. Read the + [Vault security model](/vault/docs/internals/security) and + [filtering overview](/vault/docs/concepts/filtering) to familiarize yourself + with Vault auditing and filtering basics before enabling audit devices that use + exclusions. + + + +Once you enable an audit device with exclusions, every audit entry Vault sends to +that audit device is compared to an (optional) condition in the form of a predicate expression. +Vault checks exclusions before writing to the audit log for a device. Vault modifies +any audit entries that match the exclusion expression to remove the fields +specified for that condition. You can specify multiple sets of condition and field +combinations for an individual audit device. + +When you enable audit devices that use exclusion, the behavior of any existing audit +device and the behavior of new audit devices that **do not** use exclusion remains +unchanged. + +## `exclude` option + +The value provided with the `exclude` option must be a parsable JSON array (i.e. JSON or +an escaped JSON string) of exclusion objects. + +### Exclusion object + +- `condition` `(string: )` - predicate expression using + [filtering syntax](/vault/docs/concepts/filtering). When matched, Vault removes + the values identified by `fields`. +- `fields` `(string[] )` - collection of fields in the audit entry to exclude, +identified using [JSON pointer](https://tools.ietf.org/html/rfc6901) syntax. + +```json +[ + { + "condition": "", + "fields": [ "" ] + } +] +``` + +Vault always compares exclusion conditions against the original, immutable audit +entry (the 'golden source'). As a result, evaluating a given condition does not +affect the evaluation of subsequent conditions. + +### Exclusion examples + +#### Exclude response data (when present) + +Exclude the response `data` field from any audit entry that contains it: + +```json +[ + { + "fields": [ "/response/data" ] + } +] +``` + +#### Exclude request data (when present) for transit mounts + +Exclude the request `data` field for audit entries with a mount type of `transit`: + +```json +[ + { + "condition": "\"/request/mount_type\" == transit", + "fields": [ "/request/data" ] + } +] +``` +#### Multiple exclusions + +Use multiple JSON objects to exclude: + +* `data` from both the request and response when the mount type is `transit`. +* `entity_id` from requests where the `/auth/client_token` starts with `hmac` + followed by at least one other character. + +```json +[ + { + "condition": "\"/request/mount_type\" == transit", + "fields": [ "/request/data", "/response/data" ] + }, + { + "condition": "\"/auth/client_token\" matches \"hmac.+\"", + "fields": [ "/auth/entity_id" ] + } +] +``` + +## Audit entry structure + +To accurately construct `condition` and `fields`, Vault operators need a solid +understanding of their audit entry structures. At a high level, there are only +**request** audit entries and **response** audit entries, but each of these +entries can contain different objects such as `auth`, `request` and `response`. + +We strongly encourage operaters to review existing audit logs from a timeframe +of at least 2-4 weeks to better identify appropriate exclusion conditions and +fields. + +### Request audit entry + +```json +{ + "auth": , + "error": "", + "forwarded_from": "", + "request": , + "time": "", + "type": "" +} +``` + +### Response audit entry + +```json +{ + "auth": , + "error": "", + "forwarded_from": "", + "request": , + "response": , + "time": "", + "type": "" +} +``` + +### Auth object (``) + +The following auth object definition includes example data with simple types +(`string`, `bool`, `int`) and used in other JSON examples that include an +`` object. + +```json +{ + "accessor": "", + "client_token": "", + "display_name": "", + "entity_created": "", + "entity_id": "", + "external_namespace_policies": { + "allowed": true, + "granting_policies": [ + { + "name": "", + "namespace_id": "", + "namespace_path": "", + "type": "" + } + ] + }, + "identity_policies": [ + "" + ], + "metadata": {}, + "no_default_policy": false, + "num_uses": 10, + "policies": [ + "" + ], + "policy_results": { + "allowed": true, + "granting_policies": [ + { + "name": "", + "namespace_id": "", + "namespace_path": "", + "type": "" + } + ] + }, + "remaining_uses": 5, + "token_policies": [ + "" + ], + "token_issue_time": "", + "token_ttl": 3600, + "token_type": "" +} +``` + +### Request object (``) + +The following request object definition includes example data with simple types +(`string`, `bool`, `int`) and used in other JSON examples that include a +`` object. + +```json +{ + "client_certificate_serial_number": "", + "client_id": "", + "client_token": "", + "client_token_accessor": "", + "data": {}, + "id": "", + "headers": {}, + "mount_accessor": "", + "mount_class": "", + "mount_point": "", + "mount_type": "", + "mount_running_version": "", + "mount_running_sha256": "", + "mount_is_external_plugin": "", + "namespace": { + "id": "", + "path": "" + }, + "operation": "", + "path": "", + "policy_override": true, + "remote_address": "", + "remote_port": 1234, + "replication_cluster": "", + "request_uri": "", + "wrap_ttl": 60 +} +``` + +### Response object (``) + +The following response object definition includes example data with simple types +(`string`, `bool`, `int`) and used in other JSON examples that include a +`` object. + +```json +{ + "auth": , + "data": {}, + "headers": {}, + "mount_accessor": "", + "mount_class": "", + "mount_is_external_plugin": false, + "mount_point": "", + "mount_running_sha256": "", + "mount_running_plugin_version": "", + "mount_type": "", + "redirect": "", + "secret": { + "lease_id": "" + }, + "wrap_info": { + "accessor": "", + "creation_path": "", + "creation_time": "", + "token": "", + "ttl": 60, + "wrapped_accessor": "" + }, + "warnings": [ + "" + ] +} +``` + +## Request audit entry schema + +@include 'audit/request-entry-json-schema.mdx' + +## Response audit entry schema + +@include 'audit/request-entry-json-schema.mdx' diff --git a/website/content/partials/audit-options-common.mdx b/website/content/partials/audit-options-common.mdx index 391888feca..7f85b0fdd6 100644 --- a/website/content/partials/audit-options-common.mdx +++ b/website/content/partials/audit-options-common.mdx @@ -1,6 +1,12 @@ - `elide_list_responses` `(bool: false)` - See [Eliding list response bodies](/vault/docs/audit#eliding-list-response-bodies). +- `exclude` `(string: "")` - Defines a set of + rules such that, when the condition (optional) is matched, Vault removes the specified + fields from the audit entry before writing to the audit log. Refer to the + [exclusion](/vault/docs/enterprise/audit/exclusion) section of the auditing + overview for more information. + - `fallback` `(bool: false)` - Indicates whether the audit device is the fallback for filtering purposes. **Vault only supports one fallback audit device at a time**. diff --git a/website/content/partials/audit/request-entry-json-schema.mdx b/website/content/partials/audit/request-entry-json-schema.mdx new file mode 100644 index 0000000000..b4d00a08f8 --- /dev/null +++ b/website/content/partials/audit/request-entry-json-schema.mdx @@ -0,0 +1,224 @@ +```json +{ + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "client_token": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "entity_created": { + "type": "boolean" + }, + "entity_id": { + "type": "string" + }, + "external_namespace_policies": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "identity_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "no_default_policy": { + "type": "boolean" + }, + "num_uses": { + "type": "integer", + "format": "int32" + }, + "policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "policy_results": { + "type": "object", + "properties": { + "allowed": { + "type": "boolean" + }, + "granting_policies": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace_id": { + "type": "string" + }, + "namespace_path": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "type" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "allowed" + ] + }, + "remaining_uses": { + "type": "integer", + "format": "int32" + }, + "token_issue_time": { + "type": "string" + }, + "token_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_ttl": { + "type": "integer", + "format": "int64" + }, + "token_type": { + "type": "string" + } + }, + "additionalProperties": false + }, + "error": { + "type": "string" + }, + "forwarded_from": { + "type": "string" + }, + "request": { + "type": "object", + "properties": { + "client_certificate_serial_number": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "client_token": { + "type": "string" + }, + "client_token_accessor": { + "type": "string" + }, + "data": { + "type": "object", + "additionalProperties": {} + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "id": { + "type": "string" + }, + "mount_accessor": { + "type": "string" + }, + "mount_class": { + "type": "string" + }, + "mount_is_external_plugin": { + "type": "boolean" + }, + "mount_point": { + "type": "string" + }, + "mount_running_sha256": { + "type": "string" + }, + "mount_running_version": { + "type": "string" + }, + "mount_type": { + "type": "string" + }, + "namespace": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false + }, + "operation": { + "type": "string" + }, + "path": { + "type": "string" + }, + "policy_override": { + "type": "boolean" + }, + "remote_address": { + "type": "string" + }, + "remote_port": { + "type": "integer", + "format": "int32" + }, + "replication_cluster": { + "type": "string" + }, + "request_uri": { + "type": "string" + }, + "wrap_ttl": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "time": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false +} +``` diff --git a/website/content/partials/audit/response-entry-json-schema.mdx b/website/content/partials/audit/response-entry-json-schema.mdx new file mode 100644 index 0000000000..8f86c73486 --- /dev/null +++ b/website/content/partials/audit/response-entry-json-schema.mdx @@ -0,0 +1,418 @@ +```json +{ + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "client_token": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "entity_created": { + "type": "boolean" + }, + "entity_id": { + "type": "string" + }, + "external_namespace_policies": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "identity_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "no_default_policy": { + "type": "boolean" + }, + "num_uses": { + "type": "integer", + "format": "int32" + }, + "policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "policy_results": { + "type": "object", + "properties": { + "allowed": { + "type": "boolean" + }, + "granting_policies": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace_id": { + "type": "string" + }, + "namespace_path": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "type" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "allowed" + ] + }, + "remaining_uses": { + "type": "integer", + "format": "int32" + }, + "token_issue_time": { + "type": "string" + }, + "token_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_ttl": { + "type": "integer", + "format": "int64" + }, + "token_type": { + "type": "string" + } + }, + "additionalProperties": false + }, + "error": { + "type": "string" + }, + "forwarded": { + "type": "boolean" + }, + "request": { + "type": "object", + "properties": { + "client_certificate_serial_number": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "client_token": { + "type": "string" + }, + "client_token_accessor": { + "type": "string" + }, + "data": { + "type": "object", + "additionalProperties": {} + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "id": { + "type": "string" + }, + "mount_accessor": { + "type": "string" + }, + "mount_class": { + "type": "string" + }, + "mount_is_external_plugin": { + "type": "boolean" + }, + "mount_point": { + "type": "string" + }, + "mount_running_sha256": { + "type": "string" + }, + "mount_running_version": { + "type": "string" + }, + "mount_type": { + "type": "string" + }, + "namespace": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false + }, + "operation": { + "type": "string" + }, + "path": { + "type": "string" + }, + "policy_override": { + "type": "boolean" + }, + "remote_address": { + "type": "string" + }, + "remote_port": { + "type": "integer", + "format": "int32" + }, + "replication_cluster": { + "type": "string" + }, + "request_uri": { + "type": "string" + }, + "wrap_ttl": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + "response": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "client_token": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "entity_created": { + "type": "boolean" + }, + "entity_id": { + "type": "string" + }, + "external_namespace_policies": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "identity_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "no_default_policy": { + "type": "boolean" + }, + "num_uses": { + "type": "integer", + "format": "int32" + }, + "policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "policy_results": { + "type": "object", + "properties": { + "allowed": { + "type": "boolean" + }, + "granting_policies": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "namespace_id": { + "type": "string" + }, + "namespace_path": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "type" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "allowed" + ] + }, + "remaining_uses": { + "type": "integer", + "format": "int32" + }, + "token_issue_time": { + "type": "string" + }, + "token_policies": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_ttl": { + "type": "integer", + "format": "int64" + }, + "token_type": { + "type": "string" + } + }, + "additionalProperties": false + }, + "data": { + "type": "object", + "additionalProperties": {} + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "mount_accessor": { + "type": "string" + }, + "mount_class": { + "type": "string" + }, + "mount_is_external_plugin": { + "type": "boolean" + }, + "mount_point": { + "type": "string" + }, + "mount_running_plugin_version": { + "type": "string" + }, + "mount_running_sha256": { + "type": "string" + }, + "mount_type": { + "type": "string" + }, + "redirect": { + "type": "string" + }, + "secret": { + "type": "object", + "properties": { + "lease_id": { + "type": "string" + } + }, + "additionalProperties": false + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + } + }, + "wrap_info": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "creation_path": { + "type": "string" + }, + "creation_time": { + "type": "string" + }, + "token": { + "type": "string" + }, + "ttl": { + "type": "integer", + "format": "int32" + }, + "wrapped_accessor": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "time": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false +} +``` diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index 9282b5e976..66c45f14d4 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -2849,6 +2849,10 @@ { "title": "Audit", "routes": [ + { + "title": "Audit Exclusion", + "path": "enterprise/audit/exclusion" + }, { "title": "Audit Filtering", "path": "enterprise/audit/filtering"