In the last weeks, together with Claus, we've been working on a new feature: loading properties from Vault/Secrets cloud services.
It will arrive with Camel 3.16.0, currently on vote and to be released by the end of this week (24/3).
This post introduces the new features and provide some examples.
In the past there were many discussions around the possibility of managing secrets in Camel through Vault Services.
The hidden troubles are a lot when we talk about Secrets Management:
We choose to start from the beginning: retrieve secrets from a vault service and use them as properties in the Camel configuration.
In 3.16.0 we're supporting two of the main services available in the cloud space:
The Vault feature works by specifying a particular prefix while using the Properties component.
For example for AWS:
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{aws:username}}"/>
</route>
</camelContext>
or
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{gcp:username}}"/>
</route>
</camelContext>
This notation will allow to run the following workflow while starting a camel route:
usernameFor using the particular Properties Function the two requirements are adding the camel-aws-secret-manager JAR for using the AWS one or adding the camel-google-secret-manager JAR for GCP and setting up the credentials to access the cloud service.
Each of the Secret management cloud services require different parameters to complete authentication and authorization.
For both the Properties Functions currently available we provide two different approaches:
The AWS Secret Manager Properties Function configurations through enviroment variables are the following:
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=accessKey export $CAMEL_VAULT_AWS_SECRET_KEY=secretKey export $CAMEL_VAULT_AWS_REGION=region
While as Main Configuration properties it is possible to define the credentials through the following:
camel.vault.aws.accessKey = accessKey camel.vault.aws.secretKey = secretKey camel.vault.aws.region = region
The above examples are not considering the Default Credentials Provider chain coming from AWS SDK, but the Properties Function can be configured even in that way. This is how to do that through enviroment variables:
export $CAMEL_VAULT_AWS_USE_DEFAULT_CREDENTIALS_PROVIDER=true export $CAMEL_VAULT_AWS_REGION=region
This could be done even with main configuration properties:
camel.vault.aws.defaultCredentialsProvider = true camel.vault.aws.region = region
The GCP Secret Manager Properties Function configurations through enviroment variables are the following:
export $CAMEL_VAULT_GCP_SERVICE_ACCOUNT_KEY=file:////path/to/service.accountkey export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
While as Main Configuration properties it is possible to define the credentials through the following:
camel.vault.gcp.serviceAccountKey = accessKey camel.vault.gcp.projectId = secretKey
The above examples are not considering the Default Credentials Provider coming from GCP, but the Properties Function can be configured even in that way. This is how to do that through enviroment variables:
export $CAMEL_VAULT_GCP_USE_DEFAULT_INSTANCE=true export $CAMEL_VAULT_GCP_PROJECT_ID=projectId
This could be done even with main configuration properties:
camel.vault.gcp.useDefaultInstance = true camel.vault.aws.projectId = region
Some of the Secret manager services allow users to create multiple fields in a secret, like for example:
{
"username": "admin",
"password": "password123",
"engine": "postgres",
"host": "127.0.0.1",
"port": "3128",
"dbname": "db"
}
Usually the format of the secret will be a JSON. With the Properties Function related to secrets we can retrieve a single value of the secret and use it. As example:
You're able to do get single secret value in your route, like for example:
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{gcp:database/username}}"/>
</route>
</camelContext>
In this route the property will be replaced by the field username of the value of the secret named database.
It is possible to fallback to a default value. Taking back the example above, we could use:
You could specify a default value in case the particular field of secret is not present on GCP Secret Manager:
<camelContext>
<route>
<from uri="direct:start"/>
<log message="Username is {{gcp:database/username:admin}}"/>
</route>
</camelContext>
And in case something is not working, like authentication fails, secret doesn't exists or service is down, the value returned will be admin.
In the next Camel version we are planning to work on more Secret Management Services. In particular we want to add two main components to the list:
Follow the Camel's development to know more about the work in progress.
Use the Properties Functions in your projects and give us feedback, once the release 3.16.0 will be out (it's on vote in these days).
Stay tuned!