Security/Icehouse/Heat

This page documents security related details for the Heat project in the OpenStack Icehouse release.

Overview of Heat Auth Model
Heat provides a native ReST API (heat-api) and a CloudFormation compatible API (heat-api-cfn), in a similar way to many other OpenStack projects
 * ReST API uses keystone auth_token middleware
 * ReST API can optionally be configured to allow user/password authentication when heat is used in "standalone" mode (use local heat against a remote cloud you don't control)
 * The CFN compatible API uses heat-specific ec2token middleware, which relies on the keystone ec2tokens extension for signature validation

Other than API services requiring authentication, there are a couple of unique requirements:
 * We perform deferred operations when the user creates some resources, for example orchestration actions to make adjustments to an AutoScaling group after the stack has been created. We require credentials to perform these actions on behalf of the user, or the ability to perform explicit impersonation of the user via trusts.


 * Some resources create credentials to be deployed inside (implicitly untrusted) instances created as part of the stack. Two modes are supported, one where heat creates the users in the same project as the stack owner, which requires the stack owner to posses admin roles sufficient to create keystone users (this is deprecated as of Icehouse and is planned for removal in Juno).  The other model creates users on behalf of the stack owner in a heat-specific domain, where we create a project per stack and create users associated with credentials (either ec2 keypairs or randomly generated passwords at present) that are deployed inside the instance (for example to allow signalling on completion of software configuration)

Implemented Crypto
None.

Libraries

 * PyCrypto
 * Python hashlib
 * Requests (for heatclient HTTPS usage - need to investigate underlying crypto usage)

Sensitive Data
Depending on configuration, Heat stores several types of potentially sensitive data, encrypted, in the DB:


 * User credentials
 * * If heat is configured with deferred_auth_method = password then heat will encrypt and store the password provided in the context, which is mandatory for stacks containing resources which perform deferred operations on the users behalf. This mode of operation is the default for Icehouse, but we would strongly encourage deployers to move to the trusts method instead.


 * * If heat is configured with deferred_auth_method = trusts then heat will encrypt the trust ID after creating the trust between the stack owner and the heat service user. This in a merely a precaution as the trust_id cannot be consumed by any user other than the heat service user, as such this data is much less sensitive than the user credentials stored when the password method is specified.  As such this method is recommended (has been available since Havana as an option and we're planning on making it the default for Juno)


 * OS::Heat::RandomString resource data
 * The RandomString resource creates randomly generated strings, which are stored in the heat DB. Since the usage of these strings could be related to credentials, we treat them as sensitive and store them encypted.
 * See engine/resources/random_string.py


 * AWS::IAM::AccessKey resource data
 * The AccessKey resource creates an ec2 keypair with keystone, and caches the resulting data, including the secret key in the heat DB. Since this data is sensitive, we encrypt the credential ID and keypair secret key when storing it.
 * See engine/resources/user.py


 * StackUser subclasses
 * * OS::Nova::Server
 * The Server resource is a StackUser subclass, due to the requirement for signalling from in-instance when applying software configuration via SoftwareDeployment resources. This means when the POLL_SERVER_CFN transport is selected, the resource creates an ec2 keypair with keystone and caches the result, encrypted, in the Heat DB.
 * * SignalResponder resources
 * AWS::CloudFormation::WaitConditionHandle
 * OS::Heat::HARestarter
 * AWS::AutoScaling::ScalingPolicy
 * OS::Heat::ScalingPolicy
 * These resources all create a user and associated ec2 keypair to enable generation of a pre-signed URL for signalling, the ec2 keypair is created with keystone and heat caches the result, encrypted in the Heat DB.

Keys/Certificates

 * Encryption key - Protected via filesystem ownership/permissions, specified in /etc/heat/heat.conf auth_encryption_key)

Passwords

 * SSL/TLS must be enabled in Heat to prevent clients from sending passwords, tokens and other sensitive data over the network in clear-text.

Potential Improvements

 * Make trusts the default, we should avoid storing user credentials and store a trust_id instead.
 * All deployments should use stack domain users, to avoid requiring admin roles for creation of some resources, and to provide much better isolation of the credentials deployed in untrusted instances.
 * Move away from dependence on ec2 signed URLs, making them optional in favor of native authentication (e.g native signalling via trusts from ceilometer for alarms). For SoftwareDeployments there is already the option to specify either native or ec2tokens based transports, but we have some work remaining to enable full functionality to be accesible without the ec2tokens extension available in keystone (most notably the alarm notifications mentioned above, which we're planning to fix for Juno)
 * Look into alternatives to deploying random passwords and ec2 keypairs for telemetry from instances, e.g OAuth and X509 have been discussed
 * Ideally, it would be nice to not have the ec2tokens middleware in our tree, it would be better in the keystoneclient tree IMO, where e.g a common implementation could be used by the various projects which provide AWS compatibility API's (e.g the nova ec2 API)