Registry Operator Installation in EKS
Deploy JFrog Registry Operator via Helm with CRD, service accounts, and SecretRotator CustomResource for EKS.
Configure the EKS cluster with the IAM role and attach the AWS policy before installing the operator.
-
Run the following command to export the namespace and service account name for use in the procedure.
export NAMESPACE=<namespace where the passwordless access is to be configured> -
Set
SERVICE_ACCOUNT_NAMEandANNOTATIONSwith the ARN details of the IAM role.
This step is optional from release version 2.1.x.
External Service Account Support
Support for external service accounts has been added, allowing you to use an external service account. The multi-user approach sets up a pod that can take on the roles of different service accounts.
export SERVICE_ACCOUNT_NAME=<service account where the passwordless access is to be configured>
export ANNOTATIONS="eks.amazonaws.com/role-arn: arn:aws:iam::<account_number>:role/<role_name>"You can pass this to use the default resources.
Install JFrog Registry Operator
- Add the JFrog Helm Charts repository.
helm repo add jfrog https://charts.jfrog.ioIf you have already added the JFrog Helm Charts repository, run the following command to update the repository.
helm repo update- Install Custom Resource Definition (CRD) for the operator, based on the required scope.
Default Scope
The default is cluster scope.
For Cluster scope:
VERSION=v$(curl -s https://api.github.com/repos/jfrog/jfrog-registry-operator/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
kubectl apply -f https://raw.githubusercontent.com/jfrog/jfrog-registry-operator/refs/heads/${VERSION}/config/crd/bases/apps.jfrog.com_secretrotators_cluster_scope.yamlFor Namespaced scope:
VERSION=v$(curl -s https://api.github.com/repos/jfrog/jfrog-registry-operator/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
kubectl apply -f https://raw.githubusercontent.com/jfrog/jfrog-registry-operator/refs/heads/${VERSION}/config/crd/bases/apps.jfrog.com_secretrotators_namespaced_scope.yaml- Run the following command to install the JFrog Registry operator.
helm upgrade --install secretrotator jfrog/jfrog-registry-operator --set "serviceAccount.name=${SERVICE_ACCOUNT_NAME}" --set "serviceAccount.annotations=${ANNOTATIONS}" --create-namespace -n ${NAMESPACE}The operator runs with a cluster context.
-
If you skipped Step 2 (
SERVICE_ACCOUNT_NAMEandANNOTATIONS), use the command below to install the operator in a multi-user scenario.The multi-user approach allows a pod to assume the roles of different service accounts. It reads specific service accounts and uses annotations to generate temporary credentials for the ARN, which are accessible to the operator. This setup enables customers to create new users and use the JFrog operator for automatic token exchange and rotation per namespace, eliminating the need to manage secrets in the target namespace.
Grant Necessary Permissions to Service Account
In a multi-user scenario, create all service accounts using the role ARN as an annotation via the Helm chart. This updates the ClusterRole to grant the necessary permissions to each specific service account.
If you use an external service account not created by the Helm chart, update the
custom-values.yamlwith the Service Account details. This grants the necessary permissions to ClusterRole.
Create a custom-values.yaml file with service account details.
exchangedServiceAccounts:
- name: "sa1"
namespace: "<NAMESPACE>"
annotations:
eks.amazonaws.com/role-arn: <role arn>
- name: "sa2"
namespace: "<NAMESPACE>"
annotations:
eks.amazonaws.com/role-arn: <role2 arn>Namespace Creation
Namespaces are not created by the Helm chart, so you need to create them manually if you are using a different namespace for the service account. For a centralized installation, use the operator's namespace.
Run the following command to install the JFrog Registry operator.
helm upgrade --install secretrotator jfrog/jfrog-registry-operator --create-namespace -f custom-values.yaml -n ${NAMESPACE}Multiple Custom Resources
You can then utilize the service account name and namespace in your custom resources. This allows you to install multiple custom resources with different service account details.
- Run the following command to check the status of the operator.
kubectl get po -n ${NAMESPACE}Install SecretRotator Custom Resource Object
Update the secretrotator.yaml file to include the JFrog Platform URL (artifactoryUrl) and the namespace namespaceSelector.matchLabels.kubernetes.io/metadata.name.
The spec.authType field controls how the operator obtains AWS credentials:
| Value | Behavior |
|---|---|
auto | Uses EKS Pod Identity if AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE is set in the operator pod. Otherwise, it falls back to IRSA (sts:AssumeRoleWithWebIdentity using the projected service account token for the SA named in the CR). |
podIdentity | Always uses EKS Pod Identity. Credentials are sourced from AWS_CONTAINER_CREDENTIALS_FULL_URI and the token file. Requires the Pod Identity Agent, a valid association, and pods.eks.amazonaws.com trust on the IAM role. |
webIdentity | Always uses IRSA. Reads eks.amazonaws.com/role-arn from the target ServiceAccount (per spec.serviceAccount), creates a bound token for sts.amazonaws.com, and calls sts:AssumeRoleWithWebIdentity. Does not use Pod Identity env vars. |
- For
webIdentity: the ServiceAccount referenced in the SecretRotator (or the operator's default SA if omitted) must have the annotationmetadata.annotations.eks.amazonaws.com/role-arn: <IAM role ARN>, and the IAM role must trust your cluster OIDC issuer with matchingsubandaudconditions. - For
podIdentity: the operator pod must run with a ServiceAccount that has a Pod Identity association. The injected env vars areAWS_CONTAINER_CREDENTIALS_FULL_URIandAWS_CONTAINER_AUTHORIZATION_TOKEN_FILE. status.authTypeon the SecretRotator reflects the effective mechanism used (podIdentityorwebIdentity) after a successful reconcile, including whenauthType: autois set.
The following is an example of passing the Service Account name and namespace SecretRotator CR object.
spec:
serviceAccount:
name: ""
namespace: ""Secret Types
The
generictype secret contains keystokenandpassword, while thedockertype secret contains a Kubernetes image pull secret.
You can use the generatedSecrets feature to define the specifications for one or more secrets that should be automatically generated. It also supports a wide range of secret types.
secretName: The name of the secret to be generated.secretType: The type of secret to generate (for example, docker, generic, and so on).
You can also update the time taken to refresh the token (refreshTime) and apply any secret metadata (secretMetadata).
apiVersion: apps.jfrog.com/v1alpha1
kind: SecretRotator
metadata:
labels:
app.kubernetes.io/name: secretrotators.apps.jfrog.com
app.kubernetes.io/instance: secretrotator
app.kubernetes.io/created-by: artifactory-secrets-rotator
name: ""
namespace: ""
spec:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ""
generatedSecrets:
- secretName: token-imagepull-secret
secretType: docker
- secretName: token-generic-secret
secretType: generic
artifactoryUrl: ""
# artifactorySubdomains:
# - "https://docker.artifactory.company.com"
# - "https://base-images.artifactory.company.com"
authType: "" #auto, webIdentity, podIdentity
refreshTime: 30m
secretMetadata:
annotations:
annotationKey: annotationValue
labels:
labelName: labelValue
serviceAccount:
name: ""
namespace: ""
security:
enabled: false
secretNamespace:
## Secret can have cert.pem, key.pem and ca.pem keys
## NOTE: You can provide either a pair of cert.pem and key.pem, or ca.pem, or all three: cert.pem, key.pem, and ca.pem. But make sure that key needs to same as cert.pem, key.pem, and ca.pem in secret
certificateSecretName:
insecureSkipVerify: falsespec.secretName Deprecation
The use of
spec.secretNameis currently supported but will be deprecated in the near future.
By default, rotation of registry tokens is done every 75% of token expiration time, which is set to the max AWS role session timeout. If you provide a value for refreshTime , ensure that it is not longer than the max aws role session expiration.
namespaceSelector is used by the operator to select the namespaces into which the registry tokens are created. You can update the namespaceSelector value to switch to a different namespace.
secretName contains the created Docker registry secret and the value is rotated by the operator.
If the Docker registry is on an Edge server, the user with the AWS role tag must exist on the Edge server and must be tagged either manually or through access federation.
Run the following command to update the operator with the JFrog Platform URL.
kubectl apply -f secretrotator.yaml -n ${NAMESPACE}Upgrade JFrog Registry Operator
-
Update the Helm repository.
helm repo update -
Update Custom Resource Definition (CRD) for the operator, based on the required scope.
Default Scope
The default is cluster scope.
Once the CRD is updated, proceed with either the Helm approach or the Terraform approach.
For Cluster scope:
kubectl apply -f https://raw.githubusercontent.com/jfrog/jfrog-registry-operator/refs/heads/v3.0.0/config/crd/bases/apps.jfrog.com_secretrotators_cluster_scope.yamlFor Namespaced scope:
kubectl apply -f https://raw.githubusercontent.com/jfrog/jfrog-registry-operator/refs/heads/v3.0.0/config/crd/bases/apps.jfrog.com_secretrotators_namespaced_scope.yaml -
To upgrade the JFrog Registry Operator, run the following command:
Uninstall JFrog Secret Rotator operator
# Uninstall the secretrotator using the following command
helm uninstall secretrotator -n ${NAMESPACE}
# Uninstall the secretrotator object (path should be pointing to the secretrotator.yaml)
kubectl delete -f secretrotator.yaml -n ${NAMESPACE}
# Remove the CRD from the cluster
kubectl delete crd secretrotators.apps.jfrog.comUpdated 3 days ago
