Signed Push
Send signed dry-run and sync requests to the Payload endpoint.
Signed Push
pmdocs push builds a manifest, validates it locally, authenticates the upload, and posts it to the configured endpoint.
Two auth modes are supported:
- Ed25519 request signing for provider-neutral CI/local workflows.
- GitHub OIDC bearer auth for GitHub Actions without a long-lived private key.
Examples that use main-docs are using the quick-start docs set slug. Replace
it with the Payload docs set slug for the project you are syncing.
Dry Run
1pmdocs push \2 --endpoint "$DOCS_SYNC_ENDPOINT" \3 --source main-docs \4 --key-id github-actions-main \5 --private-key-file .docs-sync/docs-sync-private.pem \6 --dry-run
Dry-run is an explicit validation-only mode. Without --dry-run, push
defaults to sync mode.
Sync
1pmdocs push \2 --endpoint "$DOCS_SYNC_ENDPOINT" \3 --source main-docs \4 --key-id github-actions-main \5 --private-key-env DOCS_SYNC_PRIVATE_KEY
Sync mode requires sync.allowWrites: true on the server.
Ed25519 Request Headers
In Ed25519 mode, the CLI sends:
1X-VL-MD-DOCS-Key-Id2X-VL-MD-DOCS-Timestamp3X-VL-MD-DOCS-Nonce4X-VL-MD-DOCS-Body-SHA2565X-VL-MD-DOCS-Signature6Content-Type: application/json
The endpoint reads the manifest source, resolves the matching docs set, and then verifies the request against an Ed25519 record in the Access collection before it applies the manifest.
Private keys may be CLI-generated PKCS#8 PEM/base64 keys or unencrypted
OpenSSH Ed25519 private keys. Public keys in Docs Globals > Access may be
PKCS#8/SPKI public keys from keygen or ssh-ed25519 ... OpenSSH public keys.
GitHub OIDC
1pmdocs push \2 --endpoint "$DOCS_SYNC_ENDPOINT" \3 --source <docs-set-slug> \4 --github-oidc
In OIDC mode, the CLI sends:
1Authorization: Bearer <github-oidc-jwt>2X-VL-MD-DOCS-Body-SHA2563Content-Type: application/json
OIDC is bearer authentication, not a body signature. The server resolves the
docs set, verifies the JWT against GitHub's JWKS, checks docs-set claim
branch plus Access owner/repository records, checks the body hash, and
uses the token jti for replay protection.
OIDC does not require --repository, --branch, or --commit; those are
optional manifest metadata. The trusted repository, ref, and SHA come from the
GitHub OIDC token claims.
See the security model.