Restapi
A secure-by-default, async Rest API with hyper, tokio, bb8, kafka-threadpool, postgres and prometheus for monitoring. Includes: a working user management and authentication backend written for postgres, async s3 uploading/downloading, async publishing to kafka with mTLS for encryption in transit
Install / Use
/learn @jay-johnson/RestapiREADME
Rust Rest API Stack with User Management, Kafka Message Publishing, S3 uploads/downloads, and Prometheus for Monitoring
A secure-by-default Rest API using hyper, tokio, bb8, kafka-threadpool, postgres, and prometheus for monitoring.
Features
- User management and authentication stored in postgres
- Async s3 uploading and downloading (to/from local files or to/from memory)
- Decoupled, async kafka threadpool that uses environment variables to connect to a kafka cluster with client mtls for authentication and encryption in transit
- Async publishing for all successful user events to a kafka topic (topic default:
user.events) and partition key (key default:user-{user.id}) - Async kafka messaging for one-off messages using custom kafka topic(s), partition key(s) and custom header(s).
Overview
User
- User password reset and user email change support using one-time-use tokens that are stored in postgres.
- Users can upload and manage files stored on AWS S3 (assuming valid credentials are loaded outside this rust project).
- User passwords are hashed using argon2.
Auth
- User authentication enabled by default
- Default JWT signing keys included with documentation for building new keys as needed.
Database
- The rest api server utilizes postgres with a bb8 client threadpool.
- The postgres database requires each client connection include the postgres tls certificate authority file for encrypting data in-transit.
- Includes pg4admin for database management in a browser (deployed with podman compose).
TLS Encryption
- Includes a tls asset generator tool (./tls/create-tls-assets.sh) for building self-signed tls assets including your own private Certificate Authority (CA).
Ingress
Component | Status ---------------- | ------ Rest API Server | Listening for encrypted client connections on tcp port 3000 Postgres | Listening for encrypted client connections on tcp port 5432 (tls Certificate Authority required) pgAdmin | Listening for encrypted HTTP client connections on tcp port 5433
Getting Started
Clone the repo
git clone https://github.com/jay-johnson/restapi
cd restapi
Generate TLS Assets and a Private Certificate Authority (CA) using CFSSL
Generate new tls assets under the ./tls directory with these commands:
cd tls
./create-tls-assets.sh
cd ..
Please refer to the Generating TLS Assets with CFSSL for more information.
Generate JWT Private and Public Signing Keys
Generate new signing JWT keys under the ./jwt directory with these commands:
cd jwt
./recreate-jwt.sh
cd ..
Please refer to the How to build JWT private and public keys for the jsonwebtokens crate doc for more information.
Deploy Postgres and pgAdmin using Podman
Please refer to the Build and Deploy a Secured Postgres backend doc for more information.
Build API Server
cargo build --example server
Run API Server
export RUST_BACKTRACE=1 && export RUST_LOG=info,kafka_threadpool=info && ./target/debug/examples/server
Environment Variables
Rest API
Environment Variable | Default --------------------- | ------- SERVER_NAME_API | api SERVER_NAME_LABEL | rust-restapi API_ENDPOINT | 0.0.0.0:3000 API_TLS_DIR | ./tls/api API_TLS_CA | ./tls/ca/ca.pem API_TLS_CERT | ./tls/api/server.pem API_TLS_KEY | ./tls/api/server-key.pem
User Email Verification
Environment Variable | Default -------------------------------------- | ------- USER_EMAIL_VERIFICATION_REQUIRED | "0" USER_EMAIL_VERIFICATION_ENABLED | "1" USER_EMAIL_VERIFICATION_EXP_IN_SECONDS | "2592000"
User One-Time-Use Token Expiration for Password Recovery
Environment Variable | Default ----------------------- | ------- USER_OTP_EXP_IN_SECONDS | "2592000"
Postgres Database
Environment Variable | Default --------------------- | ------- POSTGRES_USERNAME | datawriter POSTGRES_PASSWORD | "123321" POSTGRES_ENDPOINT | 0.0.0.0:5432 POSTGRES_TLS_DIR | ./tls/postgres POSTGRES_TLS_CA | ./tls/ca/ca.pem POSTGRES_TLS_CERT | ./tls/postgres/client.pem POSTGRES_TLS_KEY | ./tls/postgres/client-key.pem POSTGRES_DB_CONN_TYPE | postgresql
Kafka Cluster
Please refer to the kafka_threadpool docs for more information.
Environment Variable | Purpose / Value
-------------------------------- | ---------------
KAFKA_PUBLISH_EVENTS | if set to true or 1 publish all user events to kafka
KAFKA_ENABLED | toggle the kafka_threadpool on with: true or 1 anything else disables the threadpool
KAFKA_LOG_LABEL | tracking label that shows up in all crate logs
KAFKA_BROKERS | comma-delimited list of brokers (host1:port,host2:port,host3:port)
KAFKA_TOPICS | comma-delimited list of supported topics
KAFKA_PUBLISH_RETRY_INTERVAL_SEC | number of seconds to sleep before each publish retry
KAFKA_PUBLISH_IDLE_INTERVAL_SEC | number of seconds to sleep if there are no message to process
KAFKA_NUM_THREADS | number of threads for the threadpool
KAFKA_TLS_CLIENT_KEY | optional - path to the kafka mTLS key (./tls/kafka-cluster-0/client-key.pem)
KAFKA_TLS_CLIENT_CERT | optional - path to the kafka mTLS certificate (./tls/kafka-cluster-0/client.pem)
KAFKA_TLS_CLIENT_CA | optional - path to the kafka mTLS certificate authority (CA) (./tls/ca/ca.pem)
KAFKA_METADATA_COUNT_MSG_OFFSETS | optional - set to anything but true to bypass counting the offsets
Sample kafka.env file
# enable the cluster
export KAFKA_ENABLED=1
export KAFKA_LOG_LABEL="ktp"
export KAFKA_BROKERS="host1:port,host2:port,host3:port"
export KAFKA_TOPICS="testing"
export KAFKA_PUBLISH_RETRY_INTERVAL_SEC="1.0"
export KAFKA_NUM_THREADS="5"
export KAFKA_TLS_CLIENT_CA="./tls/ca/ca.pem"
export KAFKA_TLS_CLIENT_CERT="./tls/kafka-cluster-0/client.pem"
export KAFKA_TLS_CLIENT_KEY="./tls/kafka-cluster-0/client-key.pem"
# the KafkaPublisher can count the offsets for each topic with "true" or "1"
export KAFKA_METADATA_COUNT_MSG_OFFSETS="true"
S3
Environment Variable | Default -------------------- | ------- S3_DATA_BUCKET | YOUR_BUCKET S3_DATA_PREFIX | /rust-restapi/tests S3_STORAGE_CLASS | STANDARD S3_DATA_UPLOAD_TO_S3 | "0"
JWT
Environment Variable | Default ------------------------------------ | ------- TOKEN_EXPIRATION_SECONDS_INTO_FUTURE | "2592000" TOKEN_ORG | example.org TOKEN_HEADER | Bearer TOKEN_ALGO_PRIVATE_KEY | ./jwt/private-key-pkcs8.pem TOKEN_ALGO_PUBLIC_KEY | ./jwt/public-key.pem SERVER_PKI_DIR_JWT | ./jwt SERVER_PASSWORD_SALT | 78197b60-c950-4339-a52c-053165a04764
Rust
Environment Variable | Default -------------------- | ------- RUST_BACKTRACE | "1" RUST_LOG | info
Debug
Environment Variable | Default -------------------- | ------- DEBUG | "1"
Docker Builds
Build Base Image
This will build an initial base image using podman. Note: this base image will not work on a different cpu chipset because the openssl libraries are compiled within the image for this base image.
./build-base.sh
Build Derived Image
By reusing the base image, this derived image only needs to recompile the server. With minimal code changes, this is a much faster build than the base image build.
./build-derived.sh
Kubernetes
Start Kafka
If you do not have a running Kafka cluster, you can deploy your own with:
https://github.com/jay-johnson/rust-with-strimzi-kafka-and-tls
Helm Chart
Deploy TLS Assets into Kubernetes
This command will deploy all jwt keys, tls assets and credentials into the dev namespace:
./deploy-kubernetes-assets.sh -e dev
Deploy the Rust Rest API into Kubernetes
Please refer to the Deploying the Rust Rest API helm chart into kubernetes guide for deploying the example helm chart into a kubernetes cluster.
By default this uses the jayjohnson/rust-restapi container image
helm upgrade --install -n dev dev-api ./charts/rust-restapi -f ./charts/rust-restapi/values.yaml
Monitoring
Prometheus
This section assumes you have a working prometheus instance already running inside kubernetes. Below is the Prometheus scrape_config to monitor the rest api deployment replica(s) within kubernetes. Note this config also assumes the api chart is running in the dev namespace:
scrape_configs:
- job_name: rust-restapi
scrape_interval: 10s
scrape_timeout: 5s
metrics_path: /metrics
scheme: https
tls_config:
insecure_skip_verify: true
static_configs:
- targets:
- dev-api.dev.svc.cluster.local:3000
Supported APIs
Here are the supported json contracts for each Request and Response based off the url. Each client request is handled by the ./src/handle_requests.rs module and returned as a response back to the client (serialization using serde_json)
User APIs
Cre
Related Skills
himalaya
344.1kCLI to manage emails via IMAP/SMTP. Use `himalaya` to list, read, write, reply, forward, search, and organize emails from the terminal. Supports multiple accounts and message composition with MML (MIME Meta Language).
tmux
344.1kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
coding-agent
344.1kDelegate coding tasks to Codex, Claude Code, or Pi agents via background process
tavily
344.1kTavily web search, content extraction, and research tools.
