Throughout this post, we’re going to look at how AWS Secrets (other secret stores can be used) are pulled into Kubernetes as secrets there and then used within a ForgeRock AM authentication tree. A use case for this is when part of the ForgeRock AM authentication tree needs to communicate with an API. The API requires an API key which isn’t stored in ForgeRock, the API keys are secured in AWS Secrets Manager. Use Kubernetes External Secrets to pull the secrets from AWS into the Kubernetes cluster.
At the time of writing ForgeRock AM version 7.0 doesn’t support referencing environment variables from scripted decision nodes, therefore a custom Java node is required to retrieve the secret and store it in the shared state of the authentication tree. The secret can then be used by a scripted decision node to set the API key in a request header and call the API.
It is possible to call System.getenv() in a scripted decision node but the java.lang.System class will require whitelisting which will open the possibility of the script writer using System.exit(int) which would terminate the JVM. Therefore, it is not an ideal solution.
In ForgeRock AM 7.1, it will be possible to reference Kubernetes secrets from within scripted decision nodes using the ‘secrets’ binding as follows:
A different option to look at on the secret management side is the ForgeRock Secret Agent which can be used to manage different types of secrets and back them up in the cloud.
The following steps are concerned with setting up Kubernetes External Secrets to pull in AWS Secrets and how they can be used as environment variables within ForgeRock AM (7.0) nodes.
Steps to pull AWS Secrets into Kubernetes
Create secret in AWS Secrets Manager
Ensure Kubernetes External Secrets is installed on K8s cluster
Create IAM User – retrieve access key ID and secret access key and set them as secrets in K8s.
Update Kubernetes External Secrets to reference the access key ID and secret access key secrets as Environment Variables, ensure the AWS Region env var is the same as where the AWS Secrets are managed.
Create an IAM role and set the policy to get and describe the particular ARN of the secret in AWS.
Ensure the IAM User created earlier can assume this new role.
Create External Secret referencing the IAM role ARN, AWS region and the AWS secret name. The Kubernetes External Secrets pod should now pull the AWS Secret into Kubernetes as a secret. If you can’t see the secret then check the Kubernetes External Secrets pod logs, it may well be a permissions problem with the IAM Role.
Secret available to ForgeRock
For ForgeRock to pick this secret up it needs to be referenced in the deployment.yaml for AM, this is located under <path-to-forgeops>/kustomize/base/am. Under spec.template.spec.containers.env in the YAML you can add the environment variable and reference the secret.
Custom Java Node
Create a custom node in a small maven project. The process method below is executed when the tree reaches the custom node, it retrieves the environment variable. It makes a copy of the sharedState and adds the environment variable value to the sharedState. The method then tells ForgeRock to go to the next node replacing the sharedState with the new one from this method.
Build the jar file
Ensure the jar is accessible from the ForgeOps directory, the AM Dockerfile you are using needs updating by adding the following line:
Redeploy ForgeRock AM
The environment variable is retrieved using the sharedState.get() function, a request is then constructed setting the API key as one of the headers, the request is then sent and the response is logged.
The next step is to configure the tree where these nodes are going to be used, go to realms/<selected-realms>/authentication/trees and either create a new tree or select an existing one to amend.
The custom node and “Scripted Decision” nodes can be dragged onto the tree. Edit the “Scripted Decision” node, select the script created earlier in the dropdown menu. Add the outcomes of the script, usually true and false but there can be other outcomes. Adjust the nodes outgoing points to the relevant nodes and save the tree.
Execute the tree
To test the tree, go to the URL for the tree – the registration one I used for example was <domain>/am/XUI/ realm=/&authIndexType=service&authIndexValue=Registration
Follow the node executions in the AM pod logs, it should also highlight any errors with the code.
With a successful tree execution the cloud secrets have been used within ForgeRock enabling APIs to be called as part of an authentication tree.