blob: 43d4bdc6fd3a7fd4765fdf1bb594d2b03d09744b [file] [log] [blame] [view]
---
title: Security Guidelines
layout: website-normal
---
## Brooklyn Server
### Web-console and REST API
Users are strongly encouraged to use HTTPS, rather than HTTP.
The use of LDAP is encouraged, rather than basic auth.
Configuration of "entitlements" is encouraged, to lock down access to the REST API for different
users.
### Brooklyn user
Users are strongly discouraged from running Brooklyn as root.
For production use-cases (i.e. where Brooklyn will never deploy to "localhost"), the user under
which Brooklyn is running should not have `sudo` rights.
### Persisted State
Use of an object store is recommended (e.g. using S3 compliant or Swift API) - thus making
use of the security features offered by the chosen object store.
File-based persistence is also supported. Permissions of the files will automatically
be 600 (i.e. read-write only by the owner). Care should be taken for permissions of the
relevant mount points, disks and directories.
## Credential Storage
For credential storage, users are strongly encouraged to consider using the "externalised
configuration" feature. This allows credentials to be retrieved from a store managed by you,
rather than being stored within YAML blueprints or `brooklyn.cfg`.
A secure credential store is strongly recommended, such as use of
[HashiCorp's Vault](https://www.vaultproject.io) - see
`org.apache.brooklyn.core.config.external.vault.VaultExternalConfigSupplier`.
## Infrastructure Access
### Cloud Credentials and Access
Users are strongly encouraged to create separate cloud credentials for Brooklyn's API access.
Users are also encouraged to (where possible) configure the cloud provider for only minimal API
access (e.g. using AWS IAM).
<!--
TODO: We should document the minimum requirements for AWS IAM required by Brooklyn
-->
### VM Image Credentials
Users are strongly discouraged from using hard-coded passwords within VM images. Most cloud
providers/APIs provide a mechanism to instead set an auto-generated password or to create an
entry in `~/.ssh/authorized_keys` (prior to the VM being returned by the cloud provider).
If a hard-coded credential is used, then Brooklyn can be configured with this "loginUser" and
"loginUser.password" (or "loginUser.privateKeyData"), and can change the password and disable
root login.
### VM Users
It is strongly discouraged to use the root user on VMs being created or managed by Brooklyn.
SSH-ing on the VM should be done on rare cases such as initial Apache Brooklyn setup,
Apache Brooklyn upgrade and other important maintenance occasions.
### SSH keys
Users are strongly encouraged to use SSH keys for VM access, rather than passwords.
This SSH key could be a file on the Brooklyn server. However, a better solution is to use the
"externalised configuration" to return the "privateKeyData". This better supports upgrading of
credentials.
## Install Artifact Downloads
When Brooklyn executes scripts on remote VMs to install software, it often requires downloading
the install artifacts. For example, this could be from an RPM repository or to retrieve `.zip`
installers.
By default, the RPM repositories will be whatever the VM image is configured with. For artifacts
to be downloaded directly, these often default to the public site (or mirror) for that software
product.
Where users have a private RPM repository, it is strongly encouraged to ensure the VMs are
configured to point at this.
For other artifacts, users should consider hosting these artifacts in their own web-server and
configuring Brooklyn to use this. See the documentation for
`org.apache.brooklyn.core.entity.drivers.downloads.DownloadProducerFromProperties`.
## Controlling Sensitive Information
Often it is necessary to include sensitive information such as credentials within blueprints and locations.
Apache Brooklyn provides a secure mechanism for users to protect the integrity of this information, as follows:
* Values should be set in a secure external store such as an HSM, Vault, AWS Secrets Manager, or properties file
* The blueprint should provide a reference to these values in config keys
using [externalized configuration](/guide/ops/externalized-configuration.md)
* Config keys where these values are referenced should comply with the naming scheme below,
where one of the "sensitive-named tokens" is contained in the key name
Externalized configuration allows blueprints to be written such that they do not contain any secure information,
and with the steps above Apache Brooklyn further guarantees that these values of config keys are not stored on disk
as part of the catalog nor as part of an active deployment, they are not written to the log, and they are not
displayed in the UI. Because the values are needed for blueprint execution, there are still ways that users with
appropriate permissions can discover these values, such as by using them in scripts or using low-level API calls,
so due care should be taken to secure the user entitlements, the Brooklyn server, and the systems under management.
### Sensitive-Named Fields
Potentially sensitive information is identified heuristically, by default according to a naming scheme
whereby config keys and environment variables are deemed potentially sensitive if they contain any of
the following "sensitive-named tokens" (case insensitive):
- `password`
- `passwd`
- `credential`
- `secret`
- `private`
- `access.cert`
- `access.key`
This list can be customized by setting `brooklyn.security.sensitive.fields.tokens` in
`etc/brooklyn.cfg` to a list of strings, e.g. instead of the list above, to treat keys
containing "hidden" or "pass" as potentially sensitive, set:
```
brooklyn.security.sensitive.fields.tokens=[hidden,pass]
```
Brooklyn will suppress the values of potentially sensitive information in many places, as described below,
but to ensure the values are treated as secure it is necessary to follow the naming scheme _and_
supply the values via externalized configuration.
### Preventing Plaintext Values for Sensitive Named Fields
Apache Brooklyn can be configured to disallow plaintext values for potentially sensitive config keys
with the following `/etc/brooklyn.cfg` property:
```
brooklyn.security.sensitive.fields.plaintext.blocked=true
```
With this set, Apache Brooklyn will prevent deployment of blueprints that provide plaintext values in these places,
forcing users to follow security best practice. This will apply to potentially sensitive values embedded in a blueprint
being deployed or in a blueprint from the catalog referenced by a blueprint being deployed.
This will also block some additions to the catalog where secrets are set as plaintext config
values (including types from the Composer, except in some cases where it is explicitly marked as a "template").
This does not apply to default values specified for parameters or to values supplied via Java,
as it is expected in these contexts that users are less likely to accidentally supply sensitive values in plaintext.
All functions and complex objects, including mechanisms such as `$brooklyn:literal("value")` (to escape at design-time
and evaluate as `value` at runtime), are permitted as values.
Sensitive field blocking can optionally be further restricted to exclude selected DSL values and complex objects
where the string representation (unresolved `toString`) contains selected tokens or phrases, by using the
`brooklyn.security.sensitive.fields.ext.blocked.phrases` configuration property.
For example to prevent the usage of the `literal` DSL function anywhere in a supplied expression,
the following setting can be used:
```
brooklyn.security.sensitive.fields.ext.blocked.phrases = [ "$brooklyn:literal" ]
```
### Scripts, Sensors, and other Blueprint Execution Considerations
When blueprints are executing, they will by design have access to the sensitive values,
so authors should be careful to limit their usage and maintain the security around these values.
In particular:
* The sensitive-name scheme should be followed for all parameters which might contain the sensitive value,
and these should refer to sensitive-named configuration properties which refer to an external provider
* When needed for a script, sensitive value should be should be passed as environment variables
following the sensitive-name scheme, taking their values by referring to sensitive configuration properties,
and the values should not be output by the script
* Sensitive values should not be used in template files, sensors, tags, task result, or any other places
where the value might be returned in the UI or the logs
If these steps are not followed, the security afforded by the externalized configuration might be compromised.
### Logging
Log messages which may contain sensitive information are normally logged at TRACE level.
Logging should configured such that TRACE is excluded or appropriately secured
to prevent sensitive values from being compromised.
A commented sample configuration for enabling TRACE logging is available in
the `org.ops4j.pax.logging.cfg` logging configuration file.
With this configuration enabled, all TRACE log entries are written to the `brooklyn.trace.log` file.
Blueprint source code and some activity may be logged at DEBUG level or higher,
so, as per above, secrets should not be included in plain text in blueprints
unless the Apache Brooklyn environment and its logs are appropriately secured.
If it is desired to suppress information that is logged at DEBUG or higher level,
which should not ordinarily be needed but may be desired on occasion,
this can be done by setting filter(s) and/or appender(s) on the appropriate logging category in
`org.ops4j.pax.logging.cfg`. Some of the categories (or individual sub-categories of these)
which may be relevant for exclusion or higher security are:
* `org.apache.brooklyn.core.typereg`:
resolution of bundles and registration of types
* `org.apache.brooklyn.rest.resources`:
log REST activity, including blueprints deployed
* `org.apache.brooklyn.camp.brooklyn.spi.creation`:
creation of entities from CAMP
* `org.apache.brooklyn.camp.brooklyn.spi.dsl`:
resolution of DSL expressions
### Sanitizing Outputs
For security against accidental exposure, plaintext values for sensitive named fields are
masked in many places in the logs and UI,
typically replaced with a string indicating it is suppressed and supplying a MD5 hash prefix
(the first 4 bytes / 8 hex chars).
This is so that if you know the value, you can confirm it with high confidence,
but attackers don't have enough information to
uniquely crack typical-length passwords.
For example, in the logs and in the UI, sensitive information might be displayed as:
password: <suppressed> (MD5 hash prefix: 0A721B3B)
If you want to confirm the value of the password (in this case `TopSecret`), you can
compute the MD5 hash yourself, e.g. with `echo -n TopSecret | md5`, looking at the first
8 hex digits, and of course taking care to run the command in a secure location!
Note that in some places (eg if plaintext values are embedded in blueprints, contrary to
best practice) masking only applies to values set on the same line after a `:` or `=`.
If the value is supplied on a different line, possibly with comments in between,
the value will not be masked; and in addition, in some places masking is not practical,
such as in the Composer. Thus security through the sensitive-name scheme alone should
not be relied upon, and where guarantees about the integrity of sensitive information are
required, it must be used alongside the externalized configuration.