The GitOps secrets engine monitors a Git repository and applies declarative Stronghold configuration when new commits have enough verified signatures.
Key properties:
- Configuration is described in YAML and applied through the Stronghold API.
- Apply state is stored in Stronghold.
- The engine connects to Stronghold with an address and token from its own configuration.
- A renewable periodic token is required. Stronghold renews it automatically 24 hours before expiration.
- Status and errors are available at
gitops/status. - The engine can manage the same Stronghold instance it runs on, or another instance.
- You can enable several mounts to manage different parts of the configuration from different repositories, within the permissions of each token.
The GitOps secrets engine is built-in. You do not need to register or load a plugin binary.
Setup
Enable the GitOps secrets engine:
d8 stronghold secrets enable gitopsBy default, the engine mounts at
gitops/. To use another path, pass-path.Configure the Git repository to monitor:
d8 stronghold write gitops/configure/git_repository \ git_repo_url="https://gitlab.example.com/org/stronghold-gitops.git" \ required_number_of_verified_signatures_on_commit=1 \ git_poll_period=1mParameter Required Default Description git_repo_urlyes (on create) — Git repository URL git_branch_nameno mainBranch to track git_poll_periodno 5mInterval between repository polls required_number_of_verified_signatures_on_commitno 0Minimum number of verified signatures on a commit before apply git_ca_certificateno empty CA certificate for Git TLS verification max_clone_size_bytesno 10485760(10 MiB)Maximum in-memory clone size in bytes; 0disables the limitIf the repository is private, configure credentials:
d8 stronghold write gitops/configure/git_credential \ username=token \ password=glpat-XXXXXXXXCreate PGP keys for commit signing:
gpg --quick-generate-key "key1 <key1@example.com>" rsa4096 gpg --quick-generate-key "key2 <key2@example.com>" rsa4096Export the public keys and upload them to Stronghold:
gpg --armor --output key1.pgp --export key1 gpg --armor --output key2.pgp --export key2 d8 stronghold write gitops/configure/trusted_pgp_public_key/key1 public_key=@key1.pgp d8 stronghold write gitops/configure/trusted_pgp_public_key/key2 public_key=@key2.pgpConfigure API access for the engine. Prefer a wrapped renewable periodic token. The engine unwraps the token and stores it; the token cannot be read back later:
TOKEN=$(d8 stronghold token create -orphan -period=7d -policy=gitops-apply \ -display-name="gitops-plugin" -wrap-ttl=1m -field=wrapping_token) d8 stronghold write gitops/configure/vault \ vault_addr=https://stronghold.example.com:8200 \ wrapping_token=$TOKENParameter Description vault_addrStronghold API address wrapping_tokenWrapped token; preferred way to pass credentials vault_tokenToken in plain form (use only if wrapping is unavailable) vault_namespaceNamespace for API calls vault_cacert_bytesPEM-encoded CA certificate for TLS verification rotateIf trueand a token is provided, create an orphan token with the same parameters and revoke the old oneGrant the token only the policies needed to manage the resources described in the Git repository.
Sign and push configuration
Install git-signatures.
Clone the configuration repository (or create a new one) and set the signing key:
git clone https://gitlab.example.com/org/stronghold-gitops.git cd stronghold-gitops gpg --list-key git config user.signingKey <KEY_ID>Add configuration files in the declarative YAML format, commit, and sign:
git add . git commit -m "Add AppRole auth method" git signatures add git signatures showExample
git signatures showoutput:Public Key ID | Status | Trust | Date | Signer Name ===================================================================================================== 0C3AAAA10E30D5F3 | VALIDSIG | ULTIMATE | Mon 22 Dec 2025 20:19:33 MSK | key1 <key1@example.com>Push the commit and signatures:
git push origin main git signatures push
After the next poll, if the commit has enough verified signatures from trusted keys, the engine applies the configuration.
Status
Check the current status:
d8 stronghold read gitops/statusThe response includes:
status— current process status or error;last_run— time of the last periodic run (neverif the engine has not run yet);last_finished_commit— hash of the last successfully applied commit;last_finished_commit_date— date of that commit.
Disable
d8 stronghold secrets disable gitopsDisabling the engine deletes its storage data for that mount, including the stored API token and apply state.