✨(collaboration) notify the backend when the worker persists new content

notify the backend when the worker persists new content for
a document, so the lists ordered by `updated_at` follow the edits made on the
collaboration server. The backend serves it on
`POST /api/v1.0/documents/{id}/content-updated/`, authenticated with a short
lived RS256 JWT the collaboration server signs (`aud: "docs-backend"`) and
the backend verifies against the JWKS the collaboration server publishes on
`/collaboration/jwks/v1` — the mirror of the admin token the backend signs to
call it, so no long lived secret is shared and either side can roll its key
on its own
This commit is contained in:
Manuel Raynaud
2026-09-21 14:46:11 +02:00
parent 6f77d73e0e
commit b2be3bd2cb
15 changed files with 939 additions and 30 deletions
+28 -12
View File
@@ -1,23 +1,39 @@
#!/usr/bin/env bash
# Generate the RSA private key signing the JWT tokens issued by the backend.
# Generate the RSA keys signing the JWT tokens exchanged between the services.
#
# Development only. The key is generated locally and never committed: it lands
# in "data/", which is gitignored. The dev stack mounts it in the backend
# containers, where JWT_PRIVATE_KEY_FILE points at it.
# Two directions, hence two keys:
# - "private.pem" signs the tokens the backend issues to call the converter and
# the collaboration server.
# - "yhub-private.pem" signs the calls the collaboration server makes to the
# backend.
#
# Idempotent: an existing key is kept. Delete the file to roll the key.
# Only the private halves exist as files: each service publishes the public half
# of its own key on its JWKS endpoint, where the other one reads it.
#
# Development only. The keys are generated locally and never committed: they
# land in "data/", which is gitignored. The dev stack mounts them in the
# containers, where the *_FILE settings point at them.
#
# Idempotent: existing keys are kept. Delete a file to roll it.
set -eo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
KEY_PATH="${REPO_DIR}/data/jwt/private.pem"
KEY_DIR="${REPO_DIR}/data/jwt"
if [ -f "${KEY_PATH}" ]; then
exit 0
mkdir -p "${KEY_DIR}"
if [ ! -f "${KEY_DIR}/private.pem" ]; then
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-out "${KEY_DIR}/private.pem" 2>/dev/null
chmod 600 "${KEY_DIR}/private.pem"
echo "✓ backend JWT private key generated in ${KEY_DIR}/private.pem"
fi
mkdir -p "$(dirname "${KEY_PATH}")"
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out "${KEY_PATH}" 2>/dev/null
chmod 600 "${KEY_PATH}"
echo "✓ JWT private key generated in ${KEY_PATH}"
if [ ! -f "${KEY_DIR}/yhub-private.pem" ]; then
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-out "${KEY_DIR}/yhub-private.pem" 2>/dev/null
chmod 600 "${KEY_DIR}/yhub-private.pem"
echo "✓ collaboration JWT private key generated in ${KEY_DIR}/yhub-private.pem"
fi