Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
e32d381
feat: conditional fips mode
cardoso Mar 4, 2026
c62104e
ci: add fips lane
cardoso Mar 5, 2026
e214b27
ci: build fips image in advance
cardoso Mar 5, 2026
21d5d19
ci: allow selecting test lanes to run
cardoso Mar 5, 2026
ef87ee8
fix: allow sha-1 for ws handshake
cardoso Mar 5, 2026
6edad0b
Revert "ci: allow selecting test lanes to run"
cardoso Mar 5, 2026
66b91a2
chore: streamline fips env vars
cardoso Mar 5, 2026
520c880
Revert "fix: allow sha-1 for ws handshake"
cardoso Mar 6, 2026
3a05211
fix(fips): use js implementation for ws handshake
cardoso Mar 6, 2026
ca24669
refactor: improve fips init script
cardoso Mar 9, 2026
9b26f5a
ci: guard against missing creds
cardoso Mar 9, 2026
e6fab01
feat(presence-service): fips mode
cardoso Mar 9, 2026
6fa589f
ci: reduce duplication of fips checks
cardoso Mar 9, 2026
5200e60
ci: fips docker compose overrides
cardoso Mar 9, 2026
8a3df2e
ci: specify targets
cardoso Mar 9, 2026
0a32b85
ci: enhance naming and streamline service matrix
cardoso Mar 9, 2026
7d31fa7
fix: set fips mode on start
cardoso Mar 9, 2026
2c00399
fix: update artifact pattern
cardoso Mar 9, 2026
0f3e217
ci: matrix generation job
cardoso Mar 9, 2026
16e10e3
feat(authorization-service): fips
cardoso Mar 10, 2026
598e950
fix(ddp-streamer): remove flaky check
cardoso Mar 10, 2026
b64264b
feat(queue-worker): fips
cardoso Mar 10, 2026
a1250c6
feat(account-service): fips
cardoso Mar 10, 2026
a1f810a
fix(ci): compose build fallback creds
cardoso Mar 10, 2026
e9f03dc
fix(ci): retry docker buildx with backoff
cardoso Mar 10, 2026
8ca8a90
feat(ci): fips image pull step service readiness checks
cardoso Mar 10, 2026
dc8bdab
feat(omnichannel-transcript): fips
cardoso Mar 11, 2026
d7fc506
ci: improve readiness checks
cardoso Mar 11, 2026
f0f6167
fix(ci): update readiness check for omnichannel-transcript service
cardoso Mar 11, 2026
35a4656
fix(ci): update image pull step to support both EE and FIPS releases
cardoso Mar 11, 2026
93d37a6
ci: make readiness check more robust
cardoso Mar 11, 2026
816969c
ci: do not skip rocketchat image in fork runs
cardoso Mar 11, 2026
864dee8
fix(fips): enhance SHA-1 handling in FIPS mode for WebSocket handshake
cardoso Mar 11, 2026
098565e
fix(fips): enhance SHA-1 handling in FIPS mode with error handling fo…
cardoso Mar 11, 2026
d7b8d47
fix(ci): remove exclusion of rocketchat-cov service from promotion pr…
cardoso Mar 11, 2026
bd2b8e4
fix(fips): improve SHA-1 handling in FIPS mode by storing updates for…
cardoso Mar 11, 2026
f203c32
chore: consistent fips checks
cardoso Mar 11, 2026
7a44fbf
fix(fips): add WebSocket handshake validation for SHA-1 input in FIPS…
cardoso Mar 12, 2026
6ae49d2
fix(fips): prevent multiple calls to digest in SHA-1 mock implementat…
cardoso Mar 12, 2026
bbaeabc
fix(fips): add TEMP_DOCKERHUB_FIPS_USER and TEMP_DOCKERHUB_FIPS_PASS …
cardoso Mar 12, 2026
7718a09
fix(ci): improve service wait logic by checking for running container…
cardoso Mar 12, 2026
b746754
fix(ci): semgrep findings
cardoso Mar 13, 2026
3d075ac
chore: reduce logs
cardoso Mar 16, 2026
6fee461
chore: use --force-fips
cardoso Mar 16, 2026
7bdb308
chore: reduce diff
cardoso Mar 17, 2026
e411277
feat(ddp-streamer): use alpine for fips
cardoso Mar 27, 2026
ac83d83
feat(omnichannel-transcript): use alpine for fips
cardoso Mar 27, 2026
f333b1c
feat(account-service): use alpine for fips
cardoso Mar 27, 2026
241cd3b
feat(presence-service): use alpine for fips
cardoso Mar 27, 2026
9436a73
feat(queue-worker): use alpine for fips
cardoso Mar 27, 2026
186d1e7
fix(ci): skip publish of rocketchat-cov
cardoso Mar 30, 2026
5fadfb6
ci: fix retry loop
cardoso Mar 30, 2026
2d74084
chore: normalize dockerfiles
cardoso May 5, 2026
1acf215
ci(fips): build and publish rocketchat-fips image with temporary prod…
cardoso May 7, 2026
8672270
ci: hash pin docker/login-action
cardoso May 11, 2026
f20a8d1
fix(fips): remove temporary DockerHub org
cardoso May 11, 2026
4c3f26f
feat: use fips base image for rocketchat service
cardoso May 12, 2026
c4bcf42
feat: force fips in monolith
cardoso May 13, 2026
514ac3c
feat: show fips mode in logs
cardoso May 14, 2026
6813ca2
feat: show fips mode in statistics
cardoso May 14, 2026
8c0c2f3
chore(deps): update fips base images for node 22.22.3
cardoso May 19, 2026
8765e05
fix!(fips): use sha256 instead of md5 for 2fa fingerprint
cardoso May 21, 2026
b0750bc
fix(fips): use sha256 for meteor method rate limiting
cardoso May 21, 2026
dd6ddb1
fix(fips): install deno in monolith image
cardoso May 22, 2026
a207a87
fix(federation-matrix): change from md5 to sha256 for ETag for FIPS c…
cardoso May 22, 2026
6247508
chore(fips): reduce ci diff
cardoso May 22, 2026
c078358
refactor(ddp-streamer/fips): remove sha1 fallback
cardoso Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions .github/actions/build-docker/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ inputs:
CR_PAT:
required: true
description: 'GitHub Container Registry Personal Access Token'
DOCKER_USER:
required: false
description: 'DockerHub username (required for FIPS builds to pull private base image)'
DOCKER_PASS:
required: false
description: 'DockerHub password (required for FIPS builds to pull private base image)'
deno-version:
required: true
description: 'Deno version'
Expand All @@ -28,7 +34,7 @@ inputs:
default: 'true'
type:
required: false
description: 'production or coverage'
description: 'production, coverage, or fips'
default: 'coverage'

runs:
Expand All @@ -43,11 +49,21 @@ runs:
username: ${{ inputs.CR_USER }}
password: ${{ inputs.CR_PAT }}

- name: Login to DockerHub
# FIPS base image (rocketchat/dhi-node) lives in a private DockerHub repo and requires auth to pull.
if: inputs.type == 'fips' && github.actor != 'dependabot[bot]' && (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop')
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ inputs.DOCKER_USER }}
password: ${{ inputs.DOCKER_PASS }}

- name: Restore meteor build
if: inputs.service == 'rocketchat'
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: build-${{ inputs.type }}
# Temporary: rocketchat fips reuses existing Meteor artifacts until build-fips exists.
# PR/merge queue runs only produce build-coverage, while release/develop produce build-production.
name: build-${{ inputs.type == 'fips' && ((github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production') || inputs.type }}
path: /tmp/build

- name: Unpack meteor build
Expand Down Expand Up @@ -85,6 +101,10 @@ runs:
GITHUB_REF: ${{ github.ref }}
run: |
set -o xtrace
compose_fips_override=''
if [[ "$INPUT_TYPE" == 'fips' ]]; then
compose_fips_override='-f docker-compose-ci.fips.yml'
fi

# Removes unnecessary swc cores and sharp binaries to reduce image size
swc_arch='x64'
Expand All @@ -109,10 +129,10 @@ runs:
fi

# Get image name from docker-compose-ci.yml since rocketchat image is different from service name (rocket.chat)
IMAGE=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "$INPUT_SERVICE" '.services[$s].image')
IMAGE=$(docker compose -f docker-compose-ci.yml $compose_fips_override config --format json 2>/dev/null | jq -r --arg s "$INPUT_SERVICE" '.services[$s].image')

docker buildx bake \
-f docker-compose-ci.yml \
-f docker-compose-ci.yml $compose_fips_override \
${LOAD_OR_PUSH} \
--allow=fs.read=/tmp/build \
--set "*.tags+=${IMAGE}-gha-run-${GITHUB_RUN_ID}" \
Expand All @@ -133,6 +153,8 @@ runs:
SERVICE_SUFFIX=''
if [[ "$INPUT_SERVICE" == 'rocketchat' && "$INPUT_TYPE" == 'coverage' ]] && [[ "$GITHUB_EVENT_NAME" == 'release' || "$GITHUB_REF" == 'refs/heads/develop' ]]; then
SERVICE_SUFFIX='-cov'
elif [[ "$INPUT_TYPE" == 'fips' ]]; then
SERVICE_SUFFIX='-fips'
fi

mkdir -p "/tmp/manifests/${INPUT_SERVICE}${SERVICE_SUFFIX}/${INPUT_ARCH}"
Expand Down Expand Up @@ -160,9 +182,13 @@ runs:
TYPE: ${{ inputs.type }}
run: |
set -o xtrace
compose_fips_override=''
if [[ "$TYPE" == 'fips' ]]; then
compose_fips_override='-f docker-compose-ci.fips.yml'
fi

# Get image name from docker-compose-ci.yml
IMAGE=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "$SERVICE" '.services[$s].image')
IMAGE=$(docker compose -f docker-compose-ci.yml $compose_fips_override config --format json 2>/dev/null | jq -r --arg s "$SERVICE" '.services[$s].image')

# Create directory for image archives
mkdir -p /tmp/docker-images
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/ci-test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ jobs:
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop'
with:
pattern: ${{ inputs.release == 'ce' && 'docker-image-rocketchat-amd64-coverage' || 'docker-image-*-amd64-coverage' }}
pattern: ${{ inputs.release == 'ce' && 'docker-image-rocketchat-amd64-coverage' || (inputs.release == 'fips' && 'docker-image-*-amd64-fips' || 'docker-image-*-amd64-coverage') }}
path: /tmp/docker-images
merge-multiple: true

Expand Down Expand Up @@ -187,20 +187,22 @@ jobs:
DEBUG_LOG_LEVEL=${DEBUG_LOG_LEVEL:-0} docker compose -f docker-compose-ci.yml up -d rocketchat --wait

- name: Start containers for EE
if: inputs.release == 'ee'
if: inputs.release == 'ee' || inputs.release == 'fips'
env:
ENTERPRISE_LICENSE: ${{ inputs.enterprise-license }}
TRANSPORTER: ${{ inputs.transporter }}
COMPOSE_PROFILES: ${{ inputs.type == 'api' && 'api' || '' }}
TEST_MODE: ${{ (inputs.type == 'api' || inputs.type == 'api-livechat') && 'api' || 'true' }}
FIPS_OVERRIDE: ${{ inputs.release == 'fips' && '-f docker-compose-ci.fips.yml' || '' }}
run: |
DEBUG_LOG_LEVEL=${DEBUG_LOG_LEVEL:-0} docker compose -f docker-compose-ci.yml up -d --wait
read -r -a fips_override <<< "$FIPS_OVERRIDE"
DEBUG_LOG_LEVEL=${DEBUG_LOG_LEVEL:-0} docker compose -f docker-compose-ci.yml "${fips_override[@]}" up -d --wait

- uses: ./.github/actions/setup-playwright
if: inputs.type == 'ui'

- name: Wait services to start up
if: inputs.release == 'ee'
if: inputs.release == 'ee' || inputs.release == 'fips'
run: |
docker ps

Expand All @@ -218,7 +220,7 @@ jobs:
working-directory: ./apps/meteor
env:
WEBHOOK_TEST_URL: 'http://httpbin'
IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }}
IS_EE: ${{ (inputs.release == 'ee' || inputs.release == 'fips') && 'true' || '' }}
run: |
set -o xtrace

Expand All @@ -234,7 +236,7 @@ jobs:
working-directory: ./apps/meteor
env:
WEBHOOK_TEST_URL: 'http://httpbin'
IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }}
IS_EE: ${{ (inputs.release == 'ee' || inputs.release == 'fips') && 'true' || '' }}
run: |
set -o xtrace

Expand All @@ -249,7 +251,7 @@ jobs:
if: inputs.type == 'ui'
env:
E2E_COVERAGE: ${{ inputs.coverage == matrix.mongodb-version && 'true' || '' }}
IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }}
IS_EE: ${{ (inputs.release == 'ee' || inputs.release == 'fips') && 'true' || '' }}
REPORTER_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_ROCKETCHAT_API_KEY }}
REPORTER_ROCKETCHAT_URL: ${{ secrets.REPORTER_ROCKETCHAT_URL }}
REPORTER_JIRA_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_JIRA_ROCKETCHAT_API_KEY }}
Expand Down
123 changes: 121 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,28 @@ jobs:
- arch: arm64
service: [rocketchat]
type: coverage
# FIPS images: amd64 only, includes all microservices
- arch: amd64
service: [authorization-service]
type: fips
- arch: amd64
service: [queue-worker-service]
type: fips
- arch: amd64
service: [ddp-streamer-service]
type: fips
- arch: amd64
service: [account-service]
type: fips
- arch: amd64
service: [presence-service]
type: fips
- arch: amd64
service: [omnichannel-transcript-service]
type: fips
- arch: amd64
service: [rocketchat]
type: fips

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand All @@ -344,6 +366,8 @@ jobs:
with:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
arch: ${{ matrix.arch }}
service: ${{ matrix.service[0] }}
Expand All @@ -358,6 +382,8 @@ jobs:
with:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
arch: ${{ matrix.arch }}
service: ${{ matrix.service[1] }}
Expand All @@ -373,6 +399,8 @@ jobs:
with:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
arch: ${{ matrix.arch }}
service: ${{ matrix.service[2] }}
Expand All @@ -388,6 +416,8 @@ jobs:
with:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
arch: ${{ matrix.arch }}
service: ${{ matrix.service[3] }}
Expand All @@ -410,6 +440,7 @@ jobs:
with:
sparse-checkout: |
docker-compose-ci.yml
docker-compose-ci.fips.yml
sparse-checkout-cone-mode: false
ref: ${{ github.ref }}

Expand Down Expand Up @@ -452,6 +483,9 @@ jobs:
# Get image name from docker-compose-ci.yml since rocketchat image is different from service name (rocket.chat)
if [ "$service" == "rocketchat-cov" ]; then
IMAGE=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "rocketchat" '.services[$s].image')-cov
elif [[ "$service" == *"-fips" ]]; then
base_service="${service%-fips}"
IMAGE=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "$base_service" '.services[$s].image')-fips
else
IMAGE=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "$service" '.services[$s].image')
fi
Expand Down Expand Up @@ -679,6 +713,73 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
REPORTER_JIRA_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_JIRA_ROCKETCHAT_API_KEY }}

test-api-fips:
name: 🔨 Test API (FIPS)
needs: [checks, build-gh-docker-publish, release-versions]

uses: ./.github/workflows/ci-test-e2e.yml
with:
type: api
release: fips
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
transporter: 'nats://nats:4222'
enterprise-license: ${{ needs.release-versions.outputs.enterprise-license }}
mongodb-version: "['8.0']"
node-version: ${{ needs.release-versions.outputs.node-version }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
lowercase-repo: ${{ needs.release-versions.outputs.lowercase-repo }}
gh-docker-tag: ${{ needs.release-versions.outputs.gh-docker-tag }}
secrets:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

test-api-livechat-fips:
name: 🔨 Test API Livechat (FIPS)
needs: [checks, build-gh-docker-publish, release-versions]

uses: ./.github/workflows/ci-test-e2e.yml
with:
type: api-livechat
release: fips
transporter: 'nats://nats:4222'
enterprise-license: ${{ needs.release-versions.outputs.enterprise-license }}
mongodb-version: "['8.0']"
node-version: ${{ needs.release-versions.outputs.node-version }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
lowercase-repo: ${{ needs.release-versions.outputs.lowercase-repo }}
gh-docker-tag: ${{ needs.release-versions.outputs.gh-docker-tag }}
secrets:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

test-ui-fips:
name: 🔨 Test UI (FIPS)
needs: [checks, build-gh-docker-publish, release-versions]

uses: ./.github/workflows/ci-test-e2e.yml
with:
type: ui
release: fips
transporter: 'nats://nats:4222'
enterprise-license: ${{ needs.release-versions.outputs.enterprise-license }}
shard: '[1, 2, 3, 4, 5]'
total-shard: 5
mongodb-version: "['8.0']"
node-version: ${{ needs.release-versions.outputs.node-version }}
deno-version: ${{ needs.release-versions.outputs.deno-version }}
lowercase-repo: ${{ needs.release-versions.outputs.lowercase-repo }}
gh-docker-tag: ${{ needs.release-versions.outputs.gh-docker-tag }}
retries: ${{ (github.event_name == 'release' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master') && 2 || 0 }}
secrets:
CR_USER: ${{ secrets.CR_USER }}
CR_PAT: ${{ secrets.CR_PAT }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
QASE_API_TOKEN: ${{ secrets.QASE_API_TOKEN }}
REPORTER_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_ROCKETCHAT_API_KEY }}
REPORTER_ROCKETCHAT_URL: ${{ secrets.REPORTER_ROCKETCHAT_URL }}
REPORTER_JIRA_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_JIRA_ROCKETCHAT_API_KEY }}

test-federation-matrix:
name: 🔨 Test Federation Matrix
needs: [checks, build-gh-docker-publish, packages-build, release-versions]
Expand Down Expand Up @@ -829,7 +930,7 @@ jobs:
tests-done:
name: ✅ Tests Done
runs-on: ubuntu-24.04-arm
needs: [checks, test-unit, test-api, test-ui, test-api-ee, test-ui-ee, test-api-livechat, test-api-livechat-ee, test-federation-matrix]
needs: [checks, test-unit, test-api, test-ui, test-api-ee, test-ui-ee, test-api-livechat, test-api-livechat-ee, test-api-fips, test-api-livechat-fips, test-ui-fips, test-federation-matrix]
if: always()
steps:
- name: Test finish aggregation
Expand Down Expand Up @@ -866,6 +967,18 @@ jobs:
exit 1
fi

if [[ '${{ needs.test-api-fips.result }}' != 'success' ]]; then
exit 1
fi

if [[ '${{ needs.test-api-livechat-fips.result }}' != 'success' ]]; then
exit 1
fi

if [[ '${{ needs.test-ui-fips.result }}' != 'success' ]]; then
exit 1
fi

if [[ '${{ needs.test-federation-matrix.result }}' != 'success' ]]; then
exit 1
fi
Expand Down Expand Up @@ -938,6 +1051,7 @@ jobs:
with:
sparse-checkout: |
docker-compose-ci.yml
docker-compose-ci.fips.yml
sparse-checkout-cone-mode: false
ref: ${{ github.ref }}

Expand Down Expand Up @@ -1021,7 +1135,12 @@ jobs:
fi

# Get image name from docker-compose-ci.yml since rocketchat image is different from service name (rocket.chat)
SRC=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "${service}" '.services[$s].image')
if [[ "$service" == *"-fips" ]]; then
base_service="${service%-fips}"
SRC=$(docker compose -f docker-compose-ci.yml -f docker-compose-ci.fips.yml config --format json 2>/dev/null | jq -r --arg s "$base_service" '.services[$s].image')
else
SRC=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "${service}" '.services[$s].image')
fi
DEST_REPO="docker.io/${IMAGE_NAME}"

echo "Copying $SRC to ${DEST_REPO}:${PRIMARY}"
Expand Down
Loading
Loading