# Harbor Registry HTPASSWD Setup Instructions ## Problem Fixed The Harbor Helm chart requires TWO credential keys for registry authentication: - `REGISTRY_PASSWD` - plain text password - `REGISTRY_HTPASSWD` - bcrypt-hashed htpasswd format Previously, only REGISTRY_PASSWD was configured, causing Harbor registry pod failures. ## Solution Implemented **Option B: Pre-stored hash in 1Password** This approach was chosen because: 1. Aligns with mk-labs pattern of storing credentials directly in 1Password 2. More maintainable and predictable than template-based hashing 3. Simpler to troubleshoot and validate 4. No dependency on ExternalSecrets template engine capabilities ## 1Password Setup Required ### Step 1: Generate the htpasswd hash You need to generate a bcrypt hash of the registry password. The username must be `harbor_registry_user`. **Using Python (recommended):** ```bash python3 -c "import bcrypt; password=input('Enter registry password: '); print(f'harbor_registry_user:{bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=10)).decode()}')" ``` **Using htpasswd tool (if available):** ```bash htpasswd -nbB harbor_registry_user ``` ### Step 2: Add field to 1Password 1. Open 1Password and navigate to: **mk-labs vault** → **the-seas** item 2. Add a new field: - **Label:** `registry-htpasswd` - **Type:** password/text field - **Value:** The full htpasswd line from Step 1 - Example format: `harbor_registry_user:$2b$10$abcd1234...` ### Step 3: Verify the configuration The ExternalSecret has been updated to pull both fields: ```yaml - secretKey: REGISTRY_PASSWD remoteRef: key: the-seas property: registry-password - secretKey: REGISTRY_HTPASSWD remoteRef: key: the-seas property: registry-htpasswd ``` ### Step 4: Apply and verify After adding the field to 1Password: ```bash # The ExternalSecret will automatically sync within 1h, or force sync: kubectl delete externalsecret harbor-credentials -n harbor kubectl apply -f /home/hermes/git/homelab/cluster/platform/harbor/externalsecret.yaml # Verify the secret contains both keys: kubectl get secret harbor-credentials -n harbor -o jsonpath='{.data}' | jq 'keys' ``` Expected output should include both: - `REGISTRY_PASSWD` - `REGISTRY_HTPASSWD` ## Verification Commands ```bash # Check if secret exists and has correct keys kubectl get secret harbor-credentials -n harbor -o json | jq '.data | keys' # Verify REGISTRY_HTPASSWD format (should show username:$2b$...) kubectl get secret harbor-credentials -n harbor -o jsonpath='{.data.REGISTRY_HTPASSWD}' | base64 -d # Check Harbor registry pod logs for authentication success kubectl logs -n harbor -l component=registry --tail=50 ``` ## Troubleshooting **ExternalSecret not syncing:** - Check ExternalSecret status: `kubectl describe externalsecret harbor-credentials -n harbor` - Verify 1Password Connect is running: `kubectl get pods -n external-secrets` - Check that field name matches exactly: `registry-htpasswd` (lowercase, hyphen) **Hash format issues:** - Ensure bcrypt hash starts with `$2b$` or `$2a$` - Verify full line includes username: `harbor_registry_user:` - No extra whitespace or newlines in the 1Password field **Registry pod still failing:** - Verify Harbor values.yaml references the correct existingSecret name - Check registry pod environment variables contain both keys - Review registry pod logs for specific authentication errors ## Files Modified - `/home/hermes/git/homelab/cluster/platform/harbor/externalsecret.yaml` - Added REGISTRY_HTPASSWD secretKey mapping - Updated documentation comment with new field name ## Reference Harbor Helm Chart documentation: https://github.com/goharbor/harbor-helm/blob/main/values.yaml Search for "REGISTRY_HTPASSWD" to see the requirement in the values.yaml file.