-
Notifications
You must be signed in to change notification settings - Fork 23
feat: support deploying ZTVP from private git repositories #140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sabre1041
merged 6 commits into
validatedpatterns:main
from
minmzzhang:ztvp-private-repos
Jun 5, 2026
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
867c516
feat: support deploying ZTVP from private git repositories
minmzzhang 491ca2a
fix: add insecureIgnoreHostKey for SSH auth and improve troubleshooting
minmzzhang 62dc5ea
fix: ztvp-certificates merges existing proxy CA on private repo installs
minmzzhang cb9264d
fix: remove ACM workaround, bump ACM chart to 0.2.x
minmzzhang 0ba3e2a
docs: fold origin validation skip into deploy step
minmzzhang 1e82458
docs: address PR review - SSH origin validation and known hosts
minmzzhang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,247 @@ | ||
| # Deploying from a Private Repository | ||
|
|
||
| This document describes how to deploy the Layered Zero Trust Validated Pattern | ||
| from a private Git repository. | ||
|
|
||
| The Validated Patterns framework supports deploying from both SSH-secured and | ||
| HTTPS-secured (PAT) private repositories. The mechanism works by creating an | ||
| ArgoCD repository secret **before** the pattern is deployed, so that the VP | ||
| operator can propagate credentials to all ArgoCD instances managed by the | ||
| pattern. | ||
|
|
||
| > [!NOTE] | ||
| > The upstream documentation is at | ||
| > <https://validatedpatterns.io/learn/private-repos/>. This page provides | ||
| > ZTVP-specific guidance that builds on the framework docs. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| * An OpenShift 4.16+ cluster with `oc` CLI access | ||
| * A fork or private copy of this repository | ||
| * A deploy key (SSH) or Personal Access Token (HTTPS) with **read** access | ||
|
|
||
| > [!IMPORTANT] | ||
| > The git remote URL in your local clone **must match** the auth type in | ||
| > your `bootstrap_secrets`. The Makefile passes the remote URL to the | ||
| > Pattern CR verbatim when `TOKEN_SECRET` is set: | ||
| > | ||
| > * SSH auth: remote must be `git@host:org/repo.git` | ||
| > * HTTPS/PAT auth: remote must be `https://host/org/repo.git` | ||
| > | ||
| > Set with: `git remote set-url origin <matching-url>` | ||
|
|
||
| ## Option A: SSH Key Authentication | ||
|
|
||
| ### 1. Generate a deploy key | ||
|
|
||
| ```shell | ||
| ssh-keygen -t ed25519 -f ~/.ssh/ztvp-deploy-key -N "" | ||
| ``` | ||
|
|
||
| ### 2. Register the public key | ||
|
|
||
| Add `~/.ssh/ztvp-deploy-key.pub` as a **deploy key** in your Git hosting | ||
| provider (GitHub Settings -> Deploy keys, GitLab Settings -> Repository -> | ||
| Deploy keys, etc.). | ||
|
|
||
| ### 3. Configure values-secret | ||
|
|
||
| Copy the template and uncomment the SSH `bootstrap_secrets` block: | ||
|
|
||
| ```shell | ||
| cp values-secret.yaml.template ~/values-secret.yaml | ||
| ``` | ||
|
|
||
| Edit `~/values-secret.yaml` and uncomment **Option A** | ||
| under the "BOOTSTRAP SECRETS" section. Update the `url` field with your | ||
| repository's SSH URL: | ||
|
|
||
| ```yaml | ||
| bootstrap_secrets: | ||
| - name: private-repo | ||
| targetNamespaces: | ||
| - openshift-operators | ||
| labels: | ||
| argocd.argoproj.io/secret-type: repository | ||
| fields: | ||
| - name: type | ||
| value: git | ||
| - name: url | ||
| value: git@github.com:YOUR-ORG/layered-zero-trust.git | ||
| - name: insecureIgnoreHostKey | ||
| value: "true" | ||
| - name: sshPrivateKey | ||
| path: ~/.ssh/ztvp-deploy-key | ||
| ``` | ||
|
|
||
| ### 4. Deploy | ||
|
|
||
| ```shell | ||
| ./pattern.sh make TOKEN_SECRET=private-repo TOKEN_NAMESPACE=openshift-operators install | ||
|
minmzzhang marked this conversation as resolved.
Outdated
|
||
| ``` | ||
|
|
||
| ## Option B: HTTPS with Personal Access Token (PAT) | ||
|
|
||
| ### 1. Create a PAT | ||
|
|
||
| * **GitHub:** Settings -> Developer settings -> Personal access tokens -> | ||
| Fine-grained tokens. Grant **Contents: Read** on the target repository. | ||
| * **GitLab:** Settings -> Access Tokens. Grant **Reporter** role with | ||
| `read_repository` scope (Guest role is insufficient to clone code). | ||
|
|
||
| Store the token in a local file: | ||
|
|
||
| ```shell | ||
| mkdir -p ~/.config/validated-patterns | ||
| echo -n "ghp_xxxxxxxxxxxxxxxxxxxx" > ~/.config/validated-patterns/git-pat | ||
| chmod 600 ~/.config/validated-patterns/git-pat | ||
| ``` | ||
|
|
||
| ### 2. Configure values-secret | ||
|
|
||
| Copy the template and uncomment the HTTPS `bootstrap_secrets` block: | ||
|
|
||
| ```shell | ||
| cp values-secret.yaml.template ~/values-secret.yaml | ||
| ``` | ||
|
|
||
| Edit `~/values-secret.yaml` and uncomment **Option B** | ||
| under the "BOOTSTRAP SECRETS" section. Update the `url`, `username`, and | ||
| `password` path: | ||
|
|
||
| ```yaml | ||
| bootstrap_secrets: | ||
| - name: private-repo | ||
| targetNamespaces: | ||
| - openshift-operators | ||
| labels: | ||
| argocd.argoproj.io/secret-type: repository | ||
| fields: | ||
| - name: type | ||
| value: git | ||
| - name: url | ||
| value: https://github.com/YOUR-ORG/layered-zero-trust.git | ||
| - name: username | ||
| value: YOUR-USERNAME | ||
| - name: password | ||
| path: ~/.config/validated-patterns/git-pat | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > For GitLab, the `username` must be `oauth2`, not your GitLab handle. | ||
|
|
||
| ### 3. Deploy | ||
|
|
||
| For private repos the Makefile performs a pre-flight `git ls-remote` check | ||
| that will fail because the local machine does not have HTTPS credentials for | ||
| the private remote. Pass `DISABLE_VALIDATE_ORIGIN=true` to skip it: | ||
|
|
||
| ```shell | ||
| ./pattern.sh make DISABLE_VALIDATE_ORIGIN=true \ | ||
| TOKEN_SECRET=private-repo TOKEN_NAMESPACE=openshift-operators install | ||
| ``` | ||
|
|
||
| > [!NOTE] | ||
| > This is safe -- the cluster uses the `private-repo` secret (SSH key or PAT) | ||
| > for actual access; the validation is only a local convenience check. | ||
|
|
||
| ## How It Works | ||
|
|
||
| 1. The `bootstrap_secrets` section in `values-secret.yaml` instructs the | ||
| Validated Patterns framework to create the `private-repo` Kubernetes | ||
| Secret in the `openshift-operators` namespace **before** deploying the | ||
| pattern. | ||
|
|
||
| 2. The `argocd.argoproj.io/secret-type: repository` label tells ArgoCD to | ||
| pick up the secret as a repository credential. | ||
|
|
||
| 3. The `TOKEN_SECRET` and `TOKEN_NAMESPACE` Make variables set the | ||
| `tokenSecret` and `tokenSecretNamespace` fields on the Pattern Custom | ||
| Resource. The VP operator copies the secret as | ||
| `vp-private-repo-credentials` into `vp-gitops` (its managed ArgoCD | ||
| namespace). | ||
|
|
||
| 4. The ACM chart (0.2.x+) `vp-private-hub-policy` copies credentials from | ||
| `global.vpArgoNamespace`, which the VP operator automatically sets to | ||
| `vp-gitops`. This allows the policy to find the secret the VP operator | ||
| placed there without any manual override. | ||
|
|
||
| ## Verifying | ||
|
|
||
| After deployment, confirm the repository secret was created: | ||
|
|
||
| ```shell | ||
| oc get secret private-repo -n openshift-operators \ | ||
| -o jsonpath='{.metadata.labels.argocd\.argoproj\.io/secret-type}' | ||
| ``` | ||
|
|
||
| Expected output: `repository` | ||
|
|
||
| Confirm the VP operator propagated the credential to `vp-gitops`: | ||
|
|
||
| ```shell | ||
| oc get secret vp-private-repo-credentials -n vp-gitops \ | ||
| -o jsonpath='{.metadata.labels.argocd\.argoproj\.io/secret-type}' | ||
| ``` | ||
|
|
||
| Expected output: `repository` | ||
|
|
||
| Check the Cluster ArgoCD can see the repository: | ||
|
|
||
| ```shell | ||
| oc get application layered-zero-trust-hub -n vp-gitops \ | ||
| -o jsonpath='{.status.sync.status}' | ||
| ``` | ||
|
|
||
| Expected output: `Synced` (or `OutOfSync` if you have uncommitted changes). | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| * **ACM shows Degraded (vp-private-hub-policy NonCompliant)** -- The ACM | ||
| chart 0.1.x has `openshift-gitops` hardcoded in the private-repo policy | ||
| template, but the VP operator (0.0.70+) places credentials in | ||
| `vp-gitops`. Ensure `values-hub.yaml` uses ACM chart 0.2.x or later | ||
| (`chartVersion: 0.2.*`), which reads `global.vpArgoNamespace` -- a value | ||
| the VP operator sets automatically. | ||
|
|
||
| * **ArgoCD shows "repository not accessible"** -- Verify the SSH key or PAT | ||
| has read access. For SSH, confirm the key has no passphrase (`ssh-keygen | ||
| -y -f ~/.ssh/ztvp-deploy-key` should not prompt). | ||
|
|
||
| * **SSH: "knownhosts: key is unknown"** -- The `insecureIgnoreHostKey: "true"` | ||
| field is missing from the bootstrap secret. The ArgoCD repo-server runs | ||
| in a container without your Git host's fingerprint in known_hosts. | ||
|
|
||
| * **HTTPS: "x509: certificate signed by unknown authority"** -- This | ||
| affects internal/self-hosted GitLab instances whose TLS certificates are | ||
| signed by a corporate CA. GitHub and public GitLab (`gitlab.com`) use | ||
| publicly trusted CAs and do not require this step. | ||
|
|
||
| The corporate CA must be in the cluster trust store **before** install | ||
| because the VP operator needs it to clone the repository. Add the internal CA | ||
| as a pre-install step: | ||
|
|
||
| ```shell | ||
| oc create configmap custom-ca -n openshift-config \ | ||
| --from-file=ca-bundle.crt=/path/to/corporate-ca-bundle.pem | ||
| oc patch proxy/cluster --type=merge \ | ||
| -p '{"spec":{"trustedCA":{"name":"custom-ca"}}}' | ||
| ``` | ||
|
|
||
| Wait a few minutes for operator pods to restart with the updated bundle. | ||
|
|
||
| > [!NOTE] | ||
| > After the pattern deploys, the `ztvp-certificates` chart automatically | ||
| > merges your `custom-ca` content into its managed `ztvp-proxy-ca` | ||
| > ConfigMap and switches `proxy/cluster.spec.trustedCA` to | ||
| > `ztvp-proxy-ca`. This adds the cluster ingress and service CAs so | ||
| > that workloads like ACS Central can reach Keycloak without additional | ||
| > manual steps. You do **not** need to manually add the ingress CA to | ||
| > your `custom-ca`. | ||
|
|
||
| * **Secret not found during install** -- Ensure you ran | ||
| `./pattern.sh make load-secrets` *after* the bootstrap secret was created. | ||
| The `TOKEN_SECRET` and `TOKEN_NAMESPACE` values must match exactly. | ||
|
|
||
| * **GitLab HTTPS fails** -- Remember that GitLab PAT auth requires | ||
| `username: oauth2`, not your GitLab user handle. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any support to provide known hosts at provisioning time? I did a quick check in the VP repos and did not locate an option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the doc mentioning that the
insecureIgnoreHostKeyis only needed for self-hosted git servers, it is not needed for public git servers likegitlab.com,github.com.