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.

  1. 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>
  2. Set SERVICE_ACCOUNT_NAME and ANNOTATIONS with 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

  1. Add the JFrog Helm Charts repository.
helm repo add jfrog https://charts.jfrog.io

If you have already added the JFrog Helm Charts repository, run the following command to update the repository.

helm repo update
  1. 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.yaml

For 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
  1. 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.

  1. 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.yaml with 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.

  1. 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:

ValueBehavior
autoUses 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).
podIdentityAlways 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.
webIdentityAlways 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 annotation metadata.annotations.eks.amazonaws.com/role-arn: <IAM role ARN>, and the IAM role must trust your cluster OIDC issuer with matching sub and aud conditions.
  • For podIdentity: the operator pod must run with a ServiceAccount that has a Pod Identity association. The injected env vars are AWS_CONTAINER_CREDENTIALS_FULL_URI and AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE.
  • status.authType on the SecretRotator reflects the effective mechanism used (podIdentity or webIdentity) after a successful reconcile, including when authType: auto is set.

The following is an example of passing the Service Account name and namespace SecretRotator CR object.

spec:
  serviceAccount:
    name: "" 
    namespace: ""

Secret Types

The generic type secret contains keys token and password, while the docker type 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: false
📘

spec.secretName Deprecation

The use of spec.secretName is 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

  1. Update the Helm repository.

    helm repo update
  2. 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.yaml

    For 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
  3. 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.com