> ## Documentation Index
> Fetch the complete documentation index at: https://docs.seekr.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create SeekrFlow secrets

> Create every secret SeekrFlow reads, with the sfe CLI or by hand.

SeekrFlow reads its credentials from Kubernetes secrets in the `seekrflow` namespace. You either create the secrets directly, or store them in your secret store for External Secrets Operator to sync. Most of the values come from [Collect credentials and values](/self-managed/flow/provision/checklist).

## Secrets SeekrFlow uses

| Secret | Keys | When you need it | Where the value comes from |
| - | - | - | - |
| `seekrflow-license` | `license_key` | Always | Your Seekr account team |
| `pg-creds` | `PG_HOST`, `PG_USER`, `PG_PASS`, `PG_APP_USER`, `PG_APP_PASS` | Always | Your PostgreSQL hostname and admin account, `seekrflow_app`, and the `seekrflow_app` password you generated. See [Provision PostgreSQL](/self-managed/flow/provision/postgresql). |
| `auth-jwt` | `jwt_private.pem`, `jwt_public.pem`. In your secret store, `JWT_PRIVATE_KEY` and `JWT_PUBLIC_KEY`. | Always | You generate it |
| `auth-otp` | `OTP_PEPPER_SECRET` | Always | You generate it |
| `seekrflow-artifacts-pull-access` | Registry credentials | Always, in both the `seekrflow` and `argo-workflows` namespaces | Your Seekr registry username and token |
| `hf-token` | `HF_TOKEN` | Always | Your Hugging Face account. SeekrFlow needs the secret even if you don't download gated models. |
| `brave-search-api-key` | `BRAVE_SEARCH_API_KEY` | For agent web search | Your Brave Search API account |
| `auth-crypto` | `CRYPTO_ROOT_KEY` | With Federal Information Processing Standard (FIPS) mode or single sign-on | You generate it |
| `keycloak-credentials` | `db-user`, `db-password`, `admin-password` | With the bundled Keycloak | `seekrflow_keycloak`, and passwords you generate |
| `opensearch-credentials` | `OPENSEARCH_USER`, `OPENSEARCH_PASS` | With OpenSearch in the cluster, on-premises | You generate it |
| `appliance-storage-creds` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` | On-premises | Your object store's access keys |

## Generate your own values

With `sfe`, the `--auto-generate` option in [Create the secrets](#create-the-secrets) generates `auth-jwt`, `auth-otp`, `auth-crypto`, `keycloak-credentials`, and `opensearch-credentials`. It reuses existing values on later runs rather than replacing them.

Without `sfe`, generate them yourself:

```bash theme={null}
# auth-jwt: an RSA key pair
openssl genrsa -out jwt_private.pem 2048
openssl rsa -in jwt_private.pem -pubout -out jwt_public.pem

# auth-otp
openssl rand -hex 32

# auth-crypto
openssl rand -base64 32
```

Generate each value once. Replacing the token signing key pair signs out every user. Replacing the root key forces every user with multi-factor authentication to enroll again.

## Create the secrets

<Tabs>
  <Tab title="With the sfe CLI">
    <Steps>
      <Step title="Create the secrets">
        `sfe secrets create` prompts for each value and generates the ones it can.

        * **External Secrets Operator** – Writes each secret to your secret store, then adds the secret mappings to your values file:

          ```bash theme={null}
          sfe secrets create -f my-values.yaml --auto-generate
          ```

        * **Kubernetes secrets** – Creates the secrets in the cluster:

          ```bash theme={null}
          sfe secrets create -f my-values.yaml --auto-generate --provider kubernetes -n seekrflow
          ```

        To skip a secret you don't need, press Enter at its first prompt.
      </Step>

      <Step title="Create the image pull secret">
        `sfe` doesn't create this secret. Create it with `kubectl` in both the `seekrflow` and `argo-workflows` namespaces, whichever approach you use. Argo Workflows runs SeekrFlow's training and ingestion jobs in its own namespace, and a Kubernetes secret works only in the namespace it's in. If you mirrored the images, use your own registry and its credentials instead of Seekr's:

        ```bash theme={null}
        for ns in seekrflow argo-workflows; do
          kubectl create secret docker-registry seekrflow-artifacts-pull-access \
            --namespace "$ns" \
            --docker-server=seekr.repo.sonatype.app \
            --docker-username="$REGISTRY_USERNAME" \
            --docker-password="$REGISTRY_PASSWORD"
        done
        ```

        On-premises, also create `appliance-storage-creds` with `kubectl create secret generic`.
      </Step>
    </Steps>

    <Note>
      With Kubernetes secrets, `sfe secrets create` checks for the `seekrflow` namespace only after you enter every value. If the namespace doesn't exist, the command fails and discards what you entered. Create it first. See [Create the namespaces](/self-managed/flow/provision/cluster#create-the-namespaces).
    </Note>
  </Tab>

  <Tab title="Without the sfe CLI">
    Set these values to match the approach you chose in [Set up secret management](/self-managed/flow/provision/secret-management):

    | Setting | External Secrets Operator | Kubernetes secrets |
    | - | - | - |
    | `global.Secrets.enabled` | `true` | `false` |
    | `global.Secrets.store.create` | `true` | `false` |
    | `global.Secrets.store.provider` | Your store's configuration block. See the chart's `values.yaml` for Amazon Web Services (AWS) and Vault examples. | Not used. |
    | `global.Secrets.secrets.<name>.remoteRefs` | The path to each secret in your store. | Not used. |

    With External Secrets Operator, store each secret in your secret store under `seekrflow/<secret-name>`. With Kubernetes secrets, create each one with `kubectl create secret generic` in the `seekrflow` namespace. For example:

    ```bash theme={null}
    kubectl create secret generic auth-jwt \
      --namespace seekrflow \
      --from-file=jwt_private.pem=./jwt_private.pem \
      --from-file=jwt_public.pem=./jwt_public.pem
    ```

    Create the image pull secret in both the `seekrflow` and `argo-workflows` namespaces, whichever approach you use. Argo Workflows runs SeekrFlow's training and ingestion jobs in its own namespace, and a Kubernetes secret works only in the namespace it's in. If you mirrored the images, use your own registry and its credentials instead of Seekr's:

    ```bash theme={null}
    for ns in seekrflow argo-workflows; do
      kubectl create secret docker-registry seekrflow-artifacts-pull-access \
        --namespace "$ns" \
        --docker-server=seekr.repo.sonatype.app \
        --docker-username="$REGISTRY_USERNAME" \
        --docker-password="$REGISTRY_PASSWORD"
    done
    ```
  </Tab>
</Tabs>

## Keep copies outside the cluster

Back up the token signing key pair and the root key outside the cluster, such as in your organization's password manager. With Kubernetes secrets, the cluster holds the only copy. With External Secrets Operator, your secret store also holds a copy.

<Danger>
  If you lose the root key, users with multi-factor authentication have to enroll again. Users who signed in through single sign-on have to sign in again.
</Danger>

## Trust a private certificate authority

Some services SeekrFlow calls might use certificates from a private certificate authority, such as an internal object store or a corporate proxy. To trust them, store a certificate bundle in a secret and reference it:

```yaml theme={null}
global:
  defaults:
    trustedCA:
      existingSecret: <secret-name>
      key: ca-certificates.crt
```

<Warning>
  The bundle replaces each service's trust store rather than adding to it. Include the public root certificates and your own, or every other outbound Transport Layer Security (TLS) connection fails. `sfe preflight` warns if the bundle looks incomplete.
</Warning>

## Turn on FIPS mode

FIPS mode switches the Auth service to FIPS 140-3 approved cryptography. It needs the root key and one setting:

```yaml theme={null}
Auth:
  crypto:
    policy: fips
```

<Warning>
  FIPS mode is an install-time choice. You can't turn it on or off later. Enable it only on a fresh, empty database. The Auth service refuses to start if stored password hashes don't match the policy.
</Warning>

If you also enable the bundled Keycloak with FIPS mode, its database password must be at least 14 characters.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.