The Credential Server serves the User Service, which is defined in an OpenAPI 3.0 spec and lives in /openapi/user.yaml
.
Make sure you have Bazel installed. For more detailed instructions on some of the tools we use and how we use them, check out the Silicon Ally Developer Handbook.
Once that's done, make sure the cmd/server/configs/local.conf
is relevant for your setup. Specifically:
secret_azure_ad_*
configuration parameters are only required ifuse_local_jwts
is falsesecret_auth_private_key_data
is the Ed25519 private key used for JWT signing (and the public key is used for validation in thetestcreds
endpoint).-
To generate a new key you can run:
bazel run //scripts:run_keygen
Which will create
test_server.{pub,key}
files in the root of the project. From there it can be copied into the config, be careful to replace newlines with\n
.
-
To run the Credential Server, run:
# Run the backend
bazel run //scripts:run_server
# Note: If you want to use Azure instead of local JWTs, run
# bazel run //scripts:run_server -- --use_azure_auth
Once all dependencies are installed and the server actually starts, you'll see something that looks like:
█▀▄░█▄█░▀█▀
█▀▄░█░█░░█░
▀░▀░▀░▀░▀▀▀
░█▀▀░█▀▄░█▀▀░█▀▄░█▀▀░█▀▄░█░█
░█░░░█▀▄░█▀▀░█░█░▀▀█░█▀▄░▀▄▀
░▀▀▀░▀░▀░▀▀▀░▀▀░░▀▀▀░▀░▀░░▀░
At this point, the server is running and accessible at localhost:8080
.
The User API exists to exchange end-user credentials from an auth service (in this case, Azure AD B2C) for RMI-specific credentials. When testing locally, there are two different ways to test things out:
- Using the web frontend - This repo contains a basic web frontend in the
frontend/
directory, check out theREADME.md
there for set up and running instructions. The frontend integrates with Microsoft's MSAL.js to do the full authentication flow + credential exchange.
- Make sure to run the server with the
--use_azure_auth
flag.
- Using
genjwt
- Thegenjwt
tool uses your local keypair to generate JWTs. It can generate both thesource
JWTs (which would normally be issued by Azure AD et al) andapikey
JWTs, which are usually the result of the credential exchange
bazel run //scripts:run_genjwt
# This will output something like:
# Token: <header>.<payload>.<sig>
You can take that token from above and exchange it for API credentials, like:
# Be wary of storing sensitive credentials in your Bash (or similar) history.
APIKEY='<token from above>'
curl -H "Authorization: BEARER $APIKEY" -X POST localhost:8080/login/apikey
# This will output something like:
# {"id":"key123","key":"<another token>"}
You can use this new token to query an RMI API:
APIKEY='<the new token>'
# Check the credentials with the Test API
curl -H "Authorization: BEARER $APIKEY" -X POST localhost:8080/credentials:check
To build and run the image locally:
# Build the image
bazel build --@io_bazel_rules_go//go/config:pure //cmd/server:image_tarball
# Load it into Docker. This will print out something like:
# Loaded image ID: sha256:<image SHA>
docker load < bazel-bin/cmd/server/image_tarball/tarball.tar
docker run --rm -it sha256:<image SHA from previous step> --config=/configs/local.conf
If you get an error like:
/server: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /server)
/server: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /server)
Make sure you included the --@io_bazel_rules_go//go/config:pure
flag in bazel build
, see pure
docs. The problem is that without it, the compiled binary dynamically links glibc against your system, which may use a different version of glibc than the Docker container, which currently uses Debian 11 + glibc 2.28