Skip to content

Commit a77bd11

Browse files
committed
Add a JWT-SVID authenticator
The authenticators validates a JWT SPIFFE Verifiable Identity Document. Adds a configuration option to choose this new authenticator and also adds tests for it. Signed-off-by: Hugues de Valon <[email protected]>
1 parent 6c3d640 commit a77bd11

File tree

13 files changed

+1015
-84
lines changed

13 files changed

+1015
-84
lines changed

Cargo.lock

Lines changed: 857 additions & 68 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ name = "parsec"
1818
path = "src/bin/main.rs"
1919

2020
[dependencies]
21-
# Set to the newest interface version before releasing
2221
parsec-interface = "0.21.0"
2322
rand = { version = "0.7.3", features = ["small_rng"], optional = true }
2423
base64 = "0.12.3"
@@ -45,6 +44,8 @@ picky-asn1-x509 = { version = "0.3.2", optional = true }
4544
users = "0.10.0"
4645
libc = "0.2.77"
4746
anyhow = "1.0.32"
47+
# Using a fork until the JWT support is merged into the main rust-spiffe repository
48+
spiffe = { git = "https://github.com/hug-dev/rust-spiffe", branch = "refactor-jwt" }
4849

4950
[dev-dependencies]
5051
rand = { version = "0.7.3", features = ["small_rng"] }

ci.sh

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ if [ "$PROVIDER_NAME" = "pkcs11" ] || [ "$PROVIDER_NAME" = "all" ]; then
107107
popd
108108
fi
109109

110+
if [ "$PROVIDER_NAME" = "all" ]; then
111+
# Start SPIRE server and agent
112+
pushd /tmp/spire-0.11.1
113+
./bin/spire-server run -config conf/server/server.conf &
114+
sleep 2
115+
TOKEN=`bin/spire-server token generate -spiffeID spiffe://example.org/myagent | cut -d ' ' -f 2`
116+
./bin/spire-agent run -config conf/agent/agent.conf -joinToken $TOKEN &
117+
sleep 2
118+
# Register parsec-client-1
119+
./bin/spire-server entry create -parentID spiffe://example.org/myagent \
120+
-spiffeID spiffe://example.org/parsec-client-1 -selector unix:uid:$(id -u parsec-client-1)
121+
# Register parsec-client-2
122+
./bin/spire-server entry create -parentID spiffe://example.org/myagent \
123+
-spiffeID spiffe://example.org/parsec-client-2 -selector unix:uid:$(id -u parsec-client-2)
124+
sleep 5
125+
popd
126+
fi
127+
110128
echo "Build test"
111129
RUST_BACKTRACE=1 cargo build $FEATURES
112130

@@ -139,16 +157,31 @@ if [ "$PROVIDER_NAME" = "all" ]; then
139157
RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml all_providers::normal
140158

141159
echo "Execute all-providers multi-tenancy tests"
142-
su -c "RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_before" parsec-client-1
143-
su -c "RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-2 all_providers::multitenancy::client2" parsec-client-2
144-
su -c "RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_after" parsec-client-1
160+
# Needed because parsec-client-1 and 2 write to those locations owned by root
161+
chmod 777 /tmp/parsec/e2e_tests
162+
chmod 777 /tmp/
163+
export SPIFFE_ENDPOINT_SOCKET="unix:///tmp/agent.sock"
164+
165+
# PATH is defined before each command for user to use their own version of the Rust toolchain
166+
su -c "PATH=\"/home/parsec-client-1/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_before" parsec-client-1
167+
su -c "PATH=\"/home/parsec-client-2/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-2 all_providers::multitenancy::client2" parsec-client-2
168+
su -c "PATH=\"/home/parsec-client-1/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_after" parsec-client-1
145169
# Change the authentication method
146170
sed -i 's/^\(auth_type\s*=\s*\).*$/\1\"UnixPeerCredentials\"/' $CONFIG_PATH
147171
pkill -SIGHUP parsec
148172
sleep 5
149-
su -c "RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_before" parsec-client-1
150-
su -c "RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-2 all_providers::multitenancy::client2" parsec-client-2
151-
su -c "RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_after" parsec-client-1
173+
su -c "PATH=\"/home/parsec-client-1/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_before" parsec-client-1
174+
su -c "PATH=\"/home/parsec-client-2/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-2 all_providers::multitenancy::client2" parsec-client-2
175+
su -c "PATH=\"/home/parsec-client-1/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_after" parsec-client-1
176+
177+
# Change the authentication method
178+
sed -i 's/^\(auth_type\s*=\s*\).*$/\1\"JwtSvid\"/' $CONFIG_PATH
179+
sed -i 's@#workload_endpoint@workload_endpoint@' $CONFIG_PATH
180+
pkill -SIGHUP parsec
181+
sleep 5
182+
su -c "PATH=\"/home/parsec-client-1/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_before" parsec-client-1
183+
su -c "PATH=\"/home/parsec-client-2/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-2 all_providers::multitenancy::client2" parsec-client-2
184+
su -c "PATH=\"/home/parsec-client-1/.cargo/bin:${PATH}\";RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml --target-dir /home/parsec-client-1 all_providers::multitenancy::client1_after" parsec-client-1
152185

153186
# Last test as it changes the service configuration
154187
echo "Execute all-providers config tests"

config.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,18 @@ timeout = 200 # in milliseconds
5858
[authenticator]
5959
# (Required) Type of authenticator that will be used to authenticate clients' authentication
6060
# payloads.
61-
# Possible values: "Direct" and "UnixPeerCredentials".
61+
# Possible values: "Direct", "UnixPeerCredentials" and "JwtSvid".
6262
# WARNING: The "Direct" authenticator is only secure under specific requirements. Please make sure
6363
# to read the Recommendations on a Secure Parsec Deployment at
6464
# https://parallaxsecond.github.io/parsec-book/parsec_security/secure_deployment.html
6565
auth_type = "UnixPeerCredentials"
6666

67+
# (Required only for JwtSvid) Location of the Workload API endpoint
68+
# WARNING: only use this authenticator if the Workload API socket is TRUSTED. A malicious entity
69+
# owning that socket would have access to all the keys owned by clients using this authentication
70+
# method. This path *must* be trusted for as long as Parsec is running.
71+
#workload_endpoint="unix:///tmp/agent.sock"
72+
6773
# (Required) Configuration for the components managing key info for providers.
6874
# Defined as an array of tables: https://github.com/toml-lang/toml#user-content-array-of-tables
6975
[[key_manager]]

e2e_tests/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ publish = false
1414

1515
[dependencies]
1616
serde = { version = "1.0.115", features = ["derive"] }
17-
parsec-client = { version = "0.11.0", features = ["testing"] }
17+
#parsec-client = { version = "0.11.0", features = ["testing"] }
18+
#Just to test CI
19+
parsec-client = { git = "https://github.com/hug-dev/parsec-client-rust.git", branch = "spiffe", features = ["testing", "spiffe-auth"] }
1820
log = "0.4.11"
1921
rand = "0.7.3"
22+
env_logger = "0.7.1"
2023

2124
[dev-dependencies]
2225
ring = "0.16.15"
23-
env_logger = "0.7.1"
2426
rsa = "0.3.0"
2527
picky-asn1-x509 = "0.3.2"
2628
base64 = "0.12.3"

e2e_tests/provider_cfg/all/Dockerfile

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ RUN apt-get update && \
66
apt-get install -y git make gcc python3 python curl wget cmake && \
77
apt-get install -y automake autoconf libtool pkg-config libssl-dev libgcc1 && \
88
# These libraries are needed for bindgen as it uses libclang.so
9-
apt-get install -y clang libclang-dev libc6-dev-i386 && \
10-
# Install cargo globally to not have to install it for each user for multitenancy tests
11-
apt-get install -y cargo
9+
apt-get install -y clang libclang-dev libc6-dev-i386
1210

1311
WORKDIR /tmp
1412
RUN wget https://github.com/ARMmbed/mbed-crypto/archive/mbedcrypto-2.0.0.tar.gz
@@ -55,3 +53,17 @@ RUN softhsm2-util --init-token --slot 0 --label "Parsec Tests" --pin 123456 --so
5553
# Add users for multitenancy tests
5654
RUN useradd -m parsec-client-1
5755
RUN useradd -m parsec-client-2
56+
57+
USER parsec-client-1
58+
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
59+
60+
USER parsec-client-2
61+
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
62+
63+
# Install Rust toolchain for root
64+
USER root
65+
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
66+
ENV PATH="/root/.cargo/bin:${PATH}"
67+
68+
# Download the SPIRE server and agent
69+
RUN curl -s -N -L https://github.com/spiffe/spire/releases/download/v0.11.1/spire-0.11.1-linux-x86_64-glibc.tar.gz | tar xz

e2e_tests/provider_cfg/all/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ socket_path = "/tmp/parsec.sock"
1414

1515
[authenticator]
1616
auth_type = "Direct"
17+
#workload_endpoint="unix:///tmp/agent.sock"
1718

1819
[[key_manager]]
1920
name = "on-disk-manager"

e2e_tests/provider_cfg/tpm/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ FROM tpm2software/tpm2-tss:ubuntu-18.04
22

33
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig
44

5+
RUN apt-get update && \
6+
apt-get install -y cmake
7+
58
# Download and install TSS 2.0
69
RUN git clone https://github.com/tpm2-software/tpm2-tss.git --branch 2.3.3
710
RUN cd tpm2-tss \

e2e_tests/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ fn convert_error(err: Error) -> ResponseStatus {
5252
impl TestClient {
5353
/// Creates a TestClient instance.
5454
pub fn new() -> TestClient {
55+
// As this method is called in test, it will be called more than once per application.
56+
if let Err(_) = env_logger::try_init() {};
57+
5558
let mut basic_client = BasicClient::new_naked();
5659

5760
let ipc_handler = unix_socket::Handler::new(TEST_SOCKET_PATH.into(), Some(TEST_TIMEOUT));

e2e_tests/tests/per_provider/stress_test.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ use std::time::Duration;
55

66
#[test]
77
fn stress_test() {
8-
env_logger::init();
9-
108
let config = StressTestConfig {
119
no_threads: num_cpus::get(),
1210
req_per_thread: 250,

0 commit comments

Comments
 (0)