Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 40 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,44 @@ jobs:
env:
DISTRO: ${{matrix.os}}

build-podman:
runs-on: ubuntu-24.04
env:
DISTRO: ubuntu:noble
steps:
- uses: actions/checkout@v6

- name: Show OS information
run: cat /etc/os-release 2>/dev/null || \
echo /etc/os-release not available

- name: Install build dependencies
run: sudo --preserve-env bash .github/workflows/install-dependencies

- name: Build tang
run: |
mkdir -p build && cd build
export ninja=$(command -v ninja)
[ -z "${ninja}" ] && export ninja=$(command -v ninja-build)
meson setup .. || cat meson-logs/meson-log.txt >&2
${ninja}
export podman=$(command -v podman)
[ -n "${podman}" ] && ${podman} build -t tangd ..

- name: Run tests
run: |
cd build
if ! meson test ; then
cat meson-logs/testlog.txt >&2
exit -1
fi

- name: Show full test logs
run: |
if [ -r build/meson-logs/testlog.txt ]; then
cat build/meson-logs/testlog.txt >&2
else
echo "No test log available" >&2
fi

# vim:set ts=2 sw=2 et:
10 changes: 5 additions & 5 deletions .github/workflows/install-dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ubuntu:focal)
apt clean
apt update
apt -y install gcc pkg-config libjose-dev jose libhttp-parser-dev \
systemd gcovr curl socat iproute2 asciidoc git python3-pip ninja-build
systemd gcovr curl socat iproute2 asciidoc git python3-pip ninja-build
apt remove -y meson
pip3 install --upgrade meson
;;
Expand All @@ -16,15 +16,15 @@ debian:*|ubuntu:*)
apt clean
apt update
apt -y install gcc meson pkg-config libjose-dev jose libhttp-parser-dev \
systemd gcovr curl socat iproute2 asciidoc git
systemd gcovr curl socat iproute2 asciidoc git podman
;;

*fedora:*)
echo 'max_parallel_downloads=10' >> /etc/dnf/dnf.conf
dnf -y clean all
dnf -y --setopt=deltarpm=0 update
dnf -y install gcc meson pkgconfig libjose-devel jose llhttp-devel \
systemd gcovr curl socat iproute asciidoc git
systemd gcovr curl socat iproute asciidoc git podman
;;

centos:7)
Expand All @@ -33,7 +33,7 @@ centos:7)
yum install -y yum-utils epel-release
yum config-manager -y --set-enabled PowerTools \
|| yum config-manager -y --set-enabled powertools || :
yum -y install meson socat iproute asciidoc git
yum -y install meson socat iproute asciidoc git podman
yum-builddep -y tang
;;

Expand All @@ -43,7 +43,7 @@ centos:7)
dnf install -y dnf-plugins-core epel-release
dnf config-manager -y --set-enabled powertools \
|| dnf config-manager -y --set-enabled crb || :
dnf -y install meson socat iproute git
dnf -y install meson socat iproute git podman
dnf builddep -y tang --allowerasing --skip-broken --nobest
;;
esac
Expand Down
17 changes: 17 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM quay.io/fedora/fedora:latest AS build
RUN dnf -y --setopt=deltarpm=0 update && \
dnf -y install gcc pkgconfig meson libjose-devel jose llhttp-devel
RUN mkdir -p /build/in /build/out
COPY . /build/in/
WORKDIR /build/out
RUN meson setup ../in && ninja-build

FROM quay.io/fedora/fedora:latest AS runtime
RUN dnf -y install jose llhttp
COPY src/tang-show-keys /bin/
COPY --from=build /build/out/src/tangd /build/out/src/tangd-rotate-keys /build/out/src/tangd-keygen /bin/

VOLUME [ "/jwkdir" ]
EXPOSE 9090

CMD [ "/bin/tangd", "-l", "-p", "9090", "/jwkdir" ]
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,22 @@ and start the server:
# service tangd enable
# service tangd start

#### Docker Container
#### Docker/Podman Container

Tang is also available as a [Docker
Container](https://gitlab.com/AdrianKoshka/tang-docker-container/).
Tang can also be built as a Docker or Podman image using the included
Containerfile.

Care should be taken to ensure that, when deploying in a container cluster,
that the Tang keys are not stored on the same physical medium that you wish to
protect.
When deploying in a container cluster, care should be taken to ensure that the
Tang keys are not stored on the same physical medium that you wish to protect.

By default, this container starts in listen mode on port 9090 of all addresses
within the container, with the key directory set to the container's `/jwkdir`.
This path should be bound to a key storage location on the container host.

Note that socket activation is **not supported** for Tang Podman containers, as
Tang uses inetd-style socket activation (`Accept=yes`) rather than systemd-style
socket activation (`Accept=no`), and Podman quadlets do not support inetd-style
socket activation due to containers/podman#22874 (among other reasons).

### Building and Installing from Source

Expand Down
4 changes: 3 additions & 1 deletion tests/adv
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ adv_second_phase () {
test "$(tang-show-keys $PORT $ENDPOINT)" = "$(jose jwk thp -a "${THP_DEFAULT_HASH}" -i $TMP/db/sig.jwk)"

# Check that new keys will be created if none exist.
rm -rf "${TMP}/db" && mkdir -p "${TMP}/db"
# Use find to delete the contents here because deleting the directory
# breaks the container-volume link in Podman tests, which is a problem.
find "${TMP}/db" -mindepth 1 -depth -delete
fetch "${ENDPOINT}"/adv

# Now let's make sure the new keys were named using our default thumbprint
Expand Down
30 changes: 30 additions & 0 deletions tests/adv-podman
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh -ex
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2026 Marissa Lyndon <mari@reya.zone>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

. adv

sanity_check_podman

adv_startup

export PORT=$(random_port)
export CONTAINER=$(start_podman_server "${PORT}")
wait_for_port "${PORT}"

adv_second_phase
30 changes: 30 additions & 0 deletions tests/adv-podman-endpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh -ex
#
# Copyright (c) 2026 Marissa Lyndon <mari@reya.zone>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

. adv

sanity_check_podman

adv_startup

export PORT=$(random_port)
export ENDPOINT="/api/dee-hms"
export CONTAINER=$(start_podman_server_endpoint "${PORT}" "${ENDPOINT}")
wait_for_port "${PORT}"

adv_second_phase
2 changes: 1 addition & 1 deletion tests/adv-socat
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

. adv

sanity_check
sanity_check_socat

adv_startup

Expand Down
2 changes: 1 addition & 1 deletion tests/adv-socat-endpoint
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

. adv

sanity_check
sanity_check_socat

adv_startup

Expand Down
20 changes: 19 additions & 1 deletion tests/helpers
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,22 @@ start_standalone_server_endpoint() {
${VALGRIND} tangd -p ${1} -l ${TMP}/db -e ${2} &
}

start_podman_server() {
"${PODMAN}" run -d -p "${1}":9090 -v "${TMP}"/db:/jwkdir localhost/tangd
}

start_podman_server_endpoint() {
"${PODMAN}" run -d -p "${1}":9090 -v "${TMP}"/db:/jwkdir localhost/tangd /bin/tangd -p 9090 -l -e "${2}" /jwkdir
}

on_exit() {
if [ "${PID}" ]; then
kill "${PID}" || true
wait "${PID}" || true
fi
if [ -n "${PODMAN}" ] && [ -n "${CONTAINER}" ]; then
"${PODMAN}" stop --time 1 "${CONTAINER}"
fi
[ -d "${TMP}" ] && rm -rf "${TMP}"
}

Expand All @@ -114,11 +125,18 @@ validate_exc() {
--use deriveKey 2>/dev/null
}

sanity_check() {
sanity_check_socat() {
# Skip test if socat is not available.
[ -n "${SOCAT}" ] || exit 77
}

sanity_check_podman() {
# Skip test if podman is not available or the image does not exist.
if [ -z "${PODMAN}" ] || ! podman image exists localhost/tangd; then
exit 77
fi
}

die() {
echo "${1}" >&2
exit 1
Expand Down
13 changes: 13 additions & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ socat = find_program(
required: false
)

podman = find_program(
'podman',
required: false
)

env = environment()
env.prepend('PATH',
join_paths(meson.source_root(), 'src'),
Expand All @@ -40,10 +45,18 @@ if socat.found()
env.set('SOCAT', socat.path())
endif

if podman.found()
env.set('PODMAN', podman.path())
endif

test('adv-podman', find_program('adv-podman'), env: env, timeout: 360)
test('adv-podman-endpoint', find_program('adv-podman-endpoint'), env: env, timeout: 360)
test('adv-standalone', find_program('adv-standalone'), env: env, timeout: 360)
test('adv-standalone-endpoint', find_program('adv-standalone-endpoint'), env: env, timeout: 360)
test('adv-socat', find_program('adv-socat'), env: env, timeout: 360)
test('adv-socat-endpoint', find_program('adv-socat-endpoint'), env: env, timeout: 360)
test('rec-podman', find_program('rec-podman'), env: env, timeout: 360)
test('rec-podman-endpoint', find_program('rec-podman-endpoint'), env: env, timeout: 360)
test('rec-standalone', find_program('rec-standalone'), env: env, timeout: 360)
test('rec-standalone-endpoint', find_program('rec-standalone-endpoint'), env: env, timeout: 360)
test('rec-socat', find_program('rec-socat'), env: env, timeout: 360)
Expand Down
30 changes: 30 additions & 0 deletions tests/rec-podman
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh -ex
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2026 Marissa Lyndon <mari@reya.zone>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

. rec

sanity_check_podman

rec_startup

export PORT=$(random_port)
export CONTAINER=$(start_podman_server "${PORT}")
wait_for_port "${PORT}"

rec_second_phase
30 changes: 30 additions & 0 deletions tests/rec-podman-endpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/sh -ex
#
# Copyright (c) 2026 Marissa Lyndon <mari@reya.zone>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

. rec

sanity_check_podman

rec_startup

export PORT=$(random_port)
export ENDPOINT="api/dee-hms"
export CONTAINER=$(start_podman_server_endpoint "${PORT}" "${ENDPOINT}")
wait_for_port "${PORT}"

rec_second_phase_endpoint
2 changes: 1 addition & 1 deletion tests/rec-socat
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

. rec

sanity_check
sanity_check_socat

rec_startup

Expand Down
2 changes: 1 addition & 1 deletion tests/rec-socat-endpoint
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

. rec

sanity_check
sanity_check_socat

rec_startup

Expand Down
2 changes: 0 additions & 2 deletions tests/rec-standalone
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

. rec

sanity_check

rec_startup

# Start the server
Expand Down
Loading