diff --git a/website/data/docs-navigation.js b/website/data/docs-navigation.js index 6c8f7098e..c436e9995 100644 --- a/website/data/docs-navigation.js +++ b/website/data/docs-navigation.js @@ -23,6 +23,7 @@ export default [ category: 'configuration', content: [ 'acl', + 'audit', 'autopilot', 'client', 'consul', diff --git a/website/pages/docs/configuration/audit.mdx b/website/pages/docs/configuration/audit.mdx new file mode 100644 index 000000000..c5551fc17 --- /dev/null +++ b/website/pages/docs/configuration/audit.mdx @@ -0,0 +1,276 @@ +--- +layout: docs +page_title: audit Stanza - Agent Configuration +sidebar_title: audit +description: >- + The "audit" stanza configures the Nomad agent to configure Audit Logging + behavior. This is an Enterprise-only feature. +--- + +# `audit` Stanza + + + +The `audit` stanza configures the Nomad agent to configure Audit logging behavior. +Audit logging is an Enterprise-only feature. + +```hcl +audit { + enabled = true +} +``` + +When enabled, each HTTP request made to a nomad agent (client or server) will +generate two audit log entries. These two entries correspond to a stage, +`OperationReceived` and `OperationComplete`. Audit logging will generate a +`OperationReceived` event before the request is processed. An `OperationComplete` +event will be sent after the request has been processed, but before the response +body is returned to the end user. + +By default, with a minimally configured audit stanza (`audit { enabled = true }`) +The following default sink will be added with no filters. + +```hcl + sink "audit" { + type = "file" + delivery_guarantee = "enforced" + format = "json" + path = "/[data_dir]/audit/audit.log" + } +``` + +The sink will create an `audit.log` file located within the defined `data_dir` +directory inside an `audit` directory. `delivery_guarantee` will be set to +`"enforced"` meaning that all requests must successfully be written to the sink +in order for HTTP requests to successfully complete. + + +## `audit` Parameters + +- `enabled` `(bool: false)` - Specifies if audit logging should be enabled. + When enabled, audit logging will occur for every request, unless it is + filtered by a `filter`. + +- `sink` ([sink](#sink-stanza): default) - Configures a sink + for audit logs to be sent to. + +- `filter` ([filter](#filter-stanza): nil) - Configures a filter + to exclude matching events from being sent to audit logging sinks. + +### `sink` Stanza + +The `sink` stanza is used to make audit logging sinks for events to be +sent to. Currently only a single sink is supported. + +The key of the stanza corresponds to the name of the sink which is used +for logging purposes + +```hcl + sink "audit" { + type = "file" + delivery_guarantee = "enforced" + format = "json" + path = "/var/lib/nomad/audit/audit.log" + rotate_bytes = 100 + rotate_duration = "24h" + rotate_max_files = 10 + } +``` + +#### `sink` Parameters + +- `type` `(string: "file", required)` - Specifies the type of sink to create. + Currently only `"file"` type is supported. + +- `delivery_guarantee` `(string: "enforced", required)` - Specifies the + delivery guarantee that will be made for each audit log entry. Available + options are `"enforced"` and `"best-effort"`. `"enforced"` will + hault request execution if the audit log event fails to be written to it's sink. + `"best-effort"` will not hault request execution, meaning a request could + potentially be un-audited. + +- `format` `(string: "json", required)` - Specifies the output format to be + sent to a sink. Currently only `"json"` format is supported. + +- `path` `(string: "[data_dir]/audit/audit.log")` - Specifies the path and file + name to use for the audit log. By default Nomad will use it's configured + [`data_dir`](/docs/configuration#data_dir) for a combined path of + `/data_dir/audit/audit.log`. If `rotate_bytes` or `rotate_duration` are set + file rotation will occur. In this case the filename will be post-fixed with + a timestamp `"filename-{timestamp}.log"` + +- `rotate_bytes` `(int: 0)` - Specifies the number of bytes that should be + written to an audit log before it needs to be rotated. Unless specified, + there is no limit to the number of bytes that can be written to a log file. + +- `rotate_duration` `(duration: "24h")` - Specifies the maximum duration a + audit log should be written to before it needs to be rotated. Must be a + duration value such as 30s. + +- `rotate_max_files` `(int: 0)` - Specifies the maximum number of older audit log + file archives to keep. If 0 no files are ever deleted. + +### `filter` Stanza + +The `filter` stanza is used to create filters to filter __out__ matching events +from being written to the audit log. By default, all events will be sent to an +audit log for all stages (OperationReceived and OperationComplete). Filters +are useful for operators who want to limit the performance impact of audit +logging as well as reducing the amount of events generated. + +`endpoints`, `stages`, and `operations` support [globbed pattern](https://github.com/ryanuber/go-glob/blob/master/README.md#example) matching. + +```hcl +# Filter all requests and all stages for /ui/ and /v1/agent/health +filter "default" { + type = "HTTPEvent" + endpoints = ["/ui/", "/v1/agent/health"] + stages = ["*"] + operations = ["*"] +} + +# Filter OperationReceived GET requests for all endpoints +filter "OperationReceived GETs" { + type = "HTTPEvent" + endpoints = ["*"] + stages = ["OperationReceived"] + operations = ["GET"] +} +``` + +#### `filter` Parameters + +- `type` `(string: "HTTPEvent", required)` - Specifies the type of filter to + create. Currently only HTTPEvent is supported. + +- `endpoints` `(array: [])` - Specifies the list of endpoints to apply + the filter to. + +- `stages` `(array: [])` - Specifies the list of stages + (`"OperationReceived"`, `"OperationComplete"`, `"*"`) to apply the filter to + for a matching endpoint. + +- `operations` `(array: [])` - Specifies the list of operations to + apply the filter to for a matching endpoint. For HTTPEvent types this + corresponds to an HTTP verb (GET, PUT, POST, DELETE...). + +## Audit Log Format + +Below are two audit log entries for a request made to `/v1/job/web/summary`. +The first entry is for the `OperationReceived` stage. The second entry is for +the `OperationComplete` stage and includes the contents of the `OperationReceived` +stage plus a `response` key. + +```json +{ + "created_at": "2020-03-24T13:09:35.703869927-04:00", + "event_type": "audit", + "payload": { + "id": "8b826146-b264-af15-6526-29cb905145aa", + "stage": "OperationReceived", + "type": "audit", + "timestamp": "2020-03-24T13:09:35.703865005-04:00", + "version": 1, + "auth": { + "accessor_id": "a162f017-bcf7-900c-e22a-a2a8cbbcef53", + "name": "Bootstrap Token", + "global": true, + "create_time": "2020-03-24T17:08:35.086591881Z" + }, + "request": { + "id": "02f0ac35-c7e8-0871-5a58-ee9dbc0a70ea", + "operation": "GET", + "endpoint": "/v1/job/web/summary", + "namespace": { + "id": "default" + }, + "request_meta": { + "remote_address": "127.0.0.1:33648", + "user_agent": "Go-http-client/1.1" + }, + "node_meta": { + "ip": "127.0.0.1:4646" + } + } + } +} +{ + "created_at": "2020-03-24T13:09:35.704224536-04:00", + "event_type": "audit", + "payload": { + "id": "8b826146-b264-af15-6526-29cb905145aa", + "stage": "OperationComplete", + "type": "audit", + "timestamp": "2020-03-24T13:09:35.703865005-04:00", + "version": 1, + "auth": { + "accessor_id": "a162f017-bcf7-900c-e22a-a2a8cbbcef53", + "name": "Bootstrap Token", + "global": true, + "create_time": "2020-03-24T17:08:35.086591881Z" + }, + "request": { + "id": "02f0ac35-c7e8-0871-5a58-ee9dbc0a70ea", + "operation": "GET", + "endpoint": "/v1/job/web/summary", + "namespace": { + "id": "default" + }, + "request_meta": { + "remote_address": "127.0.0.1:33648", + "user_agent": "Go-http-client/1.1" + }, + "node_meta": { + "ip": "127.0.0.1:4646" + } + }, + "response": { + "status_code": 200 + } + } +} + +``` + +If the request returns an error the audit log will reflect the error message. + +```json +{ + "created_at": "2020-03-24T13:18:36.121978648-04:00", + "event_type": "audit", + "payload": { + "id": "21c6f97a-fbfb-1090-1e34-34d1ece57cc2", + "stage": "OperationComplete", + "type": "audit", + "timestamp": "2020-03-24T13:18:36.121428628-04:00", + "version": 1, + "auth": { + "accessor_id": "anonymous", + "name": "Anonymous Token", + "policies": [ + "anonymous" + ], + "create_time": "0001-01-01T00:00:00Z" + }, + "request": { + "id": "c696cc9e-962e-18b3-4097-e0a09070f89e", + "operation": "GET", + "endpoint": "/v1/jobs?prefix=web", + "namespace": { + "id": "default" + }, + "request_meta": { + "remote_address": "127.0.0.1:33874", + "user_agent": "Go-http-client/1.1" + }, + "node_meta": { + "ip": "127.0.0.1:4646" + } + }, + "response": { + "status_code": 403, + "error": "Permission denied" + } + } +} +``` diff --git a/website/pages/docs/configuration/index.mdx b/website/pages/docs/configuration/index.mdx index 0e5a999de..071017bde 100644 --- a/website/pages/docs/configuration/index.mdx +++ b/website/pages/docs/configuration/index.mdx @@ -120,6 +120,9 @@ testing. this address. Nomad servers will communicate to each other over RPC using the advertised Serf IP and advertised RPC Port. +- `audit` `(`[`Audit`]`: nil)` - Enterprise-only. Specifies audit logging + configuration. + - `bind_addr` `(string: "0.0.0.0")` - Specifies which address the Nomad agent should bind to for network services, including the HTTP interface as well as the internal gossip protocol and RPC mechanism. This should be @@ -328,6 +331,7 @@ http_api_response_headers { ``` [`acl`]: /docs/configuration/acl 'Nomad Agent ACL Configuration' +[`audit`]: /docs/configuration/audit 'Nomad Agent Audit Logging Configuration' [`client`]: /docs/configuration/client 'Nomad Agent client Configuration' [`consul`]: /docs/configuration/consul 'Nomad Agent consul Configuration' [`plugin`]: /docs/configuration/plugin 'Nomad Agent Plugin Configuration' diff --git a/website/pages/docs/enterprise/index.mdx b/website/pages/docs/enterprise/index.mdx index eb16696f5..173b6908d 100644 --- a/website/pages/docs/enterprise/index.mdx +++ b/website/pages/docs/enterprise/index.mdx @@ -40,7 +40,13 @@ See the [Autopilot - Redundancy Zones](/guides/operations/autopilot#redundancy-z ## Governance & Policy -Governance & Policy features are part of an add-on module that enables an organization to securely operate Nomad at scale across multiple teams through features such as Namespaces, Resource Quotas, Sentinel Policies, and Preemption. +Governance & Policy features are part of an add-on module that enables an organization to securely operate Nomad at scale across multiple teams through features such as Audit Logging, Namespaces, Resource Quotas, Sentinel Policies, and Preemption. + +### Audit Logging + +Audit Logging enables operators to secure clusters by providing a complete set of records for all user-issued actions. In Nomad Enterprise, Audit Logging can be configured to help increase the security posture of a cluster. + +See the [Audit Logging Documentation](/docs/configuration/audit) for a thorough overview. ### Namespaces