Wingman API Reference

Overview

Wingman is a Volterra-provided security sidecar that does almost all of the security-related work for the workload from identity bootstrapping, secrets management, external secrets management, certificate rotation, etc.

Every customer workload is automatically injected with this sidecar and it acts as an assistant to the customer workload. Since the sidecar executes within the same security boundary (Pod) as the workload and is only accessible by the workload, no security risk is added; quite the contrary, it allows applications to not handle sensitive material themselves.

Bootstrapped Identity

When a Pod is launched, Wingman makes API calls to Volterra Identity Service (running in Volterra Global Controller) and fetches Pod Identity in the form of x.509 certificates. Wingman writes these certificates in a volume mounted at /volterra/secrets/identity shared with all containers in the Pod. Content of the directory upon successful retrieval of these certificate will look as shown below -

$ ls -lart /volterra/secrets/identity
-rwxr-xr-x    1 root     root          1679 Feb  4 21:26 server.key
-rwxr-xr-x    1 root     root          6652 Feb  4 21:26 server.crt
-rwxr-xr-x    1 root     root          2171 Feb  4 21:26 client_ca.crt
-rwxr-xr-x    1 root     root          1675 Feb  4 21:26 client.key
-rwxr-xr-x    1 root     root          6648 Feb  4 21:26 client.crt
-rwxr-xr-x    1 root     root          2171 Feb  4 21:26 server_ca.crt

Here, client.crt and server.crt are pod-specific certificates and contains identity information like DNS names, pod labels and other Volterra-specific information (i.e. tenant, site, etc.). These identities are recognised across all the vK8s clusters for the tenant.

Wingman APIs

Wingman also starts an HTTP server at http://localhost:8070 in the application Pod. Wingman exposes APIs in the following three categories -

  • Status API - To get the status of Wingman
  • Identity APIs - To get certificates/keys/CA-Certificates
  • Secret Management APIs - To decrypt secrets

Status API

GET /status

Returns current state of the Wingman. Wingman can return one of the following states -

INITIALIZING - Wingman is still initializing and does not have identity certificates
READY - Wingman has the identity and is ready to serve
DEGRADED - Wingman identity certs are about to expire but last attempt to renew failed
HALTED - Wingman was not able to fetch identity certs and is not able to serve anymore

example:

$ curl http://localhost:8070/status
READY

Note: /status API always returns response code 200 and only fails if Wingman is not up or reachable.

Identity APIs

GET /creds/pki/server/key:

Returns private key of the server certificate in PEM format

GET /creds/pki/server/cert

Returns the server certificate chain in PEM format

GET /creds/pki/server/cert-only

Returns the server certificate (only leaf) in PEM format

GET /creds/pki/client/key

Returns private key of the client certificate in PEM format

GET /creds/pki/client/cert

Returns the client certificate chain in PEM format

GET /creds/pki/client/cert-only

Returns the client certificate (only leaf) in PEM format

GET /trust/pki/{ca_bundle_name}

Returns CA Certificates for the CA Bundle ca_bundle_name. currently, following ca_bundle_names are valid -

server_ca - Returns CA Certificates to be used to trust remote servers running in vk8s cluster
client_ca - Returns CA Certificates to be used to trust remote clients running in vk8s cluster

Secret Management API

POST /secret/unseal

This endpoint is used for decrypting Blindfold/Vault secret. The encrypted secret information needs to be passed as POST body. Currently two types of secrets can be fetched using this API - blindfold, vault.

Blindfold secrets:

For fetching a secret encrypted using Volterra Secret Management System (Blindfold), caller needs to provide Base64 Encoded Encrypted Bytes in the request body. Upon success, this API will return Base64 encoded decrypted bytes.

Request body has the following schema:

{
  "type": "blindfold",
  // Secret location
  // It must be in url format string:///
  "location": <secret_url>,
  // OPTIONAL. Encoding of the secret before it was encrypted.
  // Default is EncodingNone meaning no encoding. Other supported value is EncodingBase64.
  // If encoding_type is EncodingBase64, that means secret was Base64 encoding before it was encrypted. In that case Wingman will return the original secret back (before it was Base64 encoded).
  "encoding_type": "EncodingNone",
}

example -

$ cat request.json
{
  "type": "blindfold",
  "location": "string:///AAAACWN1c3RvbWVyMQAAAAEAAAAAAAAAiAIAAAAFA6ur/XkAAAEArc3DxZa69sWeIn9NRrHGcZlZaXLHWYjc57jIS76Z47AcU0jDmodz3lNEysVO2swNAUn8p6yiuvf8Vj4LUuWB++LdP2yYX5ftEHmMgnHTaTeW0or87X24nK4UPollx/2S9/i+tJN9VcrhCFWYHMMPx9AU7Lw7yJ7CPuv7x5EJZl/BOonWhYst1d7fb6GPMSxhqsxoR2i8aDkl1sMCaFbBv1oANfDrL1DrXnae7iXuZPGzxszeDWlZakvwek3lsWMJT4b2rhjXML2Vq4AdKFBp5zbrh15g7mS0lpdX/xG6h0+IdHyrWPoIg/hZwYyV9xmIOcFc1Jk5PZC554hchHbToQAAAQCKnfbK+kRkQDOOFC6WWHtha8DacIOY25GO5wEO58bYkeXYmtbEBfExvpE7yNndKDlKSWLHVBdS2jqVXzAYD2A4EzmZmWyo7RyCjSclbm/fSaVTN0BFI7kHllcbg6df4BuXlN6CZ2ulh0Y8qGeNGwKUQl215CYjjyX5w0ZUjbgse5nHtC0PhWV8XU7cWwtJBhziIdeQHNHvF44txeIcAhOH7DqfqVVQbq77JUm82B3e66+evUqSSb3HYWbySicv1vog/HQyFSStE3BP8q9mQxkyovY489iTiZEj7iKH3951F44waPH5GwsEB+vztkKLm59c/OaM6aVJuWazQUHsSzRBP/SWxd3/i7ATIsCeDDJW2kc578wsJ45E9G2J5o8sMVL5pTlO9Swp9V85DvQMbeeZiKNj"
}

$ curl http://localhost:8070/secret/unseal -X POST -H 'content-type: application/json' -d @request.json
VGhpcyBzZWNyZXQgaXMgZm9yIGRlbW8tdGxzLXNlcnZlcgo=

Vault Secrets:

Wingman can be used to fetch secrets store in Hashicorp Vault as well. In this case, request needs to contain handle to the Secret Management Access Object (https://docs.ves.volterra.io/api/#tag/Secret-Management-Access). Response will be Base64 encoded decrypted secret.

Request body has following schema:

{
  "type": "vault",
  // handle to the secret_management_access object to get access info to connect to vault server
  "provider": <provider_name>,
  // path to get the secret from
  "location": <secret_url>,
  // OPTIONAL. key of the individual secret. If not provided entire secret will be returned
  "key": <key_name>,
  // OPTIONAL. version of the secret to be fetched. If not provided latest version will be returned
  "version": <version>,
  // OPTIONAL. Encoding of the secret before it was put into vault
  // Default is EncodingNone meaning no encoding. Other supported value is EncodingBase64.
  // If encoding_type is EncodingBase64, that means secret was Base64 encoding before it was encrypted. In that case Wingman will return the original secret back (before it was Base64 encoded).
  "encoding_type": "EncodingBase64",
}

example -

$ cat request.json
{
  "type": "vault",
  "provider": "vault_provider_1",
  "location": "/secret/my-secret/my-secret-1",
}

$ curl http://localhost:8070/secret/unseal -X POST -H 'content-type: application/json' -d @request.json
VGhpcyBzZWNyZXQgaXMgZm9yIGRlbW8tdGxzLXNlcnZlcgo=