Secret Types - Reference

Every secret in Barbican has a type. Secret types are used to describe different kinds of secret data that are stored in Barbican. The type for a particular secret is listed in the secret’s metadata as the secret_type attribute.

The possible secret types are:

  • symmetric - Used for storing byte arrays such as keys suitable for symmetric encryption.
  • public - Used for storing the public key of an asymmetric keypair.
  • private - Used for storing the private key of an asymmetric keypair.
  • passphrase - Used for storing plain text passphrases.
  • certificate - Used for storing cryptographic certificates such as X.509 certificates.
  • opaque - Used for backwards compatibility with previous versions of the API without typed secrets. New applications are encouraged to specify one of the other secret types.

Symmetric

The symmetric secret type is used to store byte arrays of sensitive data, such as keys that are used for symmetric encryption. The content-type used with symmetric secrets is application/octet-stream. When storing a symmetric secret with a single POST request, the data must be encoded so that it may be included inside the JSON body of the request. In this case, the content encoding of base64 can be used.

Example 1.1

Create an encryption key for use in AES-256-CBC encryption and store it in Barbican. First, we’ll see how this can be done in a single POST request from the command line using curl.

# Create an encryption_key file with 256 bits of random data
dd bs=32 count=1 if=/dev/urandom of=encryption_key

# Encode the contents of the encryption key using base64 encoding
KEY_BASE64=$(base64 < encryption_key)

# Send a request to store the key in Barbican
curl -vv -H "X-Auth-Token: $TOKEN" -H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "AES encryption key",
     "secret_type": "symmetric",
     "payload": "'"$KEY_BASE64"'",
     "payload_content_type": "application/octet-stream",
     "payload_content_encoding": "base64",
     "algorithm": "AES",
     "bit_length": 256,
     "mode": "CBC"}' \
http://localhost:9311/v1/secrets | python -m json.tool

This should return a reference (URI) for the secret that was created:

{
  "secret_ref": "http://localhost:9311/v1/secrets/48d24158-b4b4-45b8-9669-d9f0ef793c23"
}

We can use this reference to retrieve the secret metadata:

curl -vv -H "X-Auth-Token: $TOKEN" -H 'Accept: application/json' \
http://localhost:9311/v1/secrets/48d24158-b4b4-45b8-9669-d9f0ef793c23 |
python -m json.tool

The metadata will list the available content-types for the symmetric secret:

{
    "algorithm": "AES",
    "bit_length": 256,
    "content_types": {
        "default": "application/octet-stream"
    },
    "created": "2015-04-08T06:24:16.600393",
    "creator_id": "3a7e3d2421384f56a8fb6cf082a8efab",
    "expiration": null,
    "mode": "CBC",
    "name": "AES encryption key",
    "secret_ref": "http://localhost:9311/v1/secrets/48d24158-b4b4-45b8-9669-d9f0ef793c23",
    "secret_type": "symmetric",
    "status": "ACTIVE",
    "updated": "2015-04-08T06:24:16.614204"
}

The content_types attribute describes the content-types that can be used to retrieve the payload. In this example, there is only the default content type of application/octet-stream. We can use it to retrieve the payload:

 # Retrieve the payload and save it to a file
curl -vv -H "X-Auth-Token: $TOKEN" \
-H 'Accept: application/octet-stream' \
-o retrieved_key \
http://localhost:9311/v1/secrets/48d24158-b4b4-45b8-9669-d9f0ef793c23/payload

The retrieved_key file now contains the byte array we started with. Note that barbican returned the byte array in binary format, not base64. This is because the payload_content_encoding is only used when submitting the secret to barbican.

Public

The public secret type is used to store the public key of an asymmetric keypair. For example, a public secret can be used to store the public key of an RSA keypair. Currently, there is only one file format accepted for public secrets: A DER-encoded SubjectPublicKeyInfo structure as defined by X.509 RFC 5280 that has been Base64 encoded with a PEM header and footer. This is the type of public key that is generated by the openssl tool by default. The content-type used with public secrets is application/octet-stream. When storing a public secret with a single POST request, the contents of the file must be encoded since JSON does not accept newline characters. In this case, the contents of the file must be Base64 encoded and the content encoding of base64 can be used.

Example 2.1

Create an RSA keypair and store the public key in Barbican. For this example, we will be using a metadata-only POST followed by a PUT.

# Create the RSA keypair
openssl genrsa -out private.pem 2048

# Extract the public key
openssl rsa -in private.pem -out public.pem -pubout

# Submit a metadata-only POST
curl -vv -H "X-Auth-Token: $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "RSA Public Key",
     "secret_type": "public",
     "algorithm": "RSA"}' \
http://localhost:9311/v1/secrets | python -m json.tool

This should return a reference (URI) for the secret that was created:

200 OK

{
  "secret_ref": "http://localhost:9311/v1/secrets/cd20d134-c229-417a-a753-86432ad13bad"
}

We can use this reference to add the payload with a PUT request:

curl -vv -X PUT -H "X-Auth-Token: $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/octet-stream' \
--data-binary @public.pem \
http://localhost:9311/v1/secrets/cd20d134-c229-417a-a753-86432ad13bad

The server should respond with a 2xx response to indicate that the PUT request was processed successfully:

204 - No Content

Now we should be able to request the metadata and see the new content-type listed there:

curl -vv -H "X-Auth-Token: $TOKEN" \
-H 'Accept: application/json' \
http://localhost:9311/v1/secrets/cd20d134-c229-417a-a753-86432ad13bad |
python -m json.tool
{
    "algorithm": "RSA",
    "bit_length": null,
    "content_types": {
        "default": "application/octet-stream"
    },
    "created": "2015-04-08T21:45:59.239976",
    "creator_id": "3a7e3d2421384f56a8fb6cf082a8efab",
    "expiration": null,
    "mode": null,
    "name": "RSA Public Key",
    "secret_ref": "http://localhost:9311/v1/secrets/cd20d134-c229-417a-a753-86432ad13bad",
    "secret_type": "public",
    "status": "ACTIVE",
    "updated": "2015-04-08T21:52:57.523969"
}

Finally, we can use the default content-type listed in content_types to retrieve the public key:

curl -vv -H "X-Auth-Token: $TOKEN" \
-H 'Accept: application/octet-stream' \
-o retrieved_public.pem \
http://localhost:9311/v1/secrets/cd20d134-c229-417a-a753-86432ad13bad/payload

The retrieved_public.pem file now has the same contents as the public.pem file we started with.

Example 2.2

Create an RSA keypair and store the public key in Barbican. For this example we will be using a single POST request.

# Create the RSA keypair
openssl genrsa -out private.pem 2048

# Extract the public key
openssl rsa -in private.pem -out public.pem -pubout

# Base64 encode the contents of the public key
PUB_BASE64=$(base64 < public.pem)

curl -vv -H "X-Auth-Token: $TOKEN" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"name": "RSA Public Key",
     "secret_type": "public",
     "payload": "'"$PUB_BASE64"'",
     "payload_content_type": "application/octet-stream",
     "payload_content_encoding": "base64",
     "algorithm": "RSA"}' \
http://localhost:9311/v1/secrets | python -m json.tool

This should return a reference (URI) for the secret that was created.

200 OK

{
  "secret_ref": "http://localhost:9311/v1/secrets/d553f0ac-c79d-43b4-b165-32594b612ad4"
}