Authentication microservice for the Smirkly platform, built with the userver framework.
Implemented:
- User registration (email + password) with persistence in Postgres
- Sign-in issuing an access token and an HttpOnly refresh-token cookie
- Refresh-token storage, rotation, reuse detection, and session revocation
- Current-session logout and all-sessions revocation
- Password change with all-sessions revocation
- Email verification flow: verification code generation and enqueueing email into outbox
- Public JWKS endpoint for access-token verification
Work in progress:
- Password reset flow
- Production deployment packaging and migration runner
- Application-level rate limiting
Status: active development. APIs, configuration, and internal structure may change without backward compatibility guarantees.
git clone https://github.com/Smirkly/smirkly-auth.git
cd smirkly-authIf you have not cloned with --recurse-submodules, initialize submodules:
git submodule update --initThis will pull third-party dependencies such as userver and libbcrypt.
Create a .env file in the project root with database settings, for example:
POSTGRES_DB=smirkly_auth
POSTGRES_USER=smirkly_auth
POSTGRES_PASSWORD=smirkly_authThese values are used by local Postgres (e.g. via docker-compose.yml) and must match the connection settings in your configs.
Create configs/config_vars.yaml with basic runtime options, for example:
worker-threads: 4
worker-fs-threads: 2
logger-level: info
is-testing: false
server-port: 8080
AUTH_JWT_AUDIENCE: smirkly-api
AUTH_JWT_KEY_ID: smirkly-auth-local-rs256
AUTH_JWT_PRIVATE_KEY_PATH: ./configs/secrets/auth_jwt_private.pem
AUTH_JWT_PUBLIC_KEY_PATH: ./configs/secrets/auth_jwt_public.pemworker-threads / worker-fs-threads – userver task processors.
logger-level – log level (trace, debug, info, warning, error…).
server-port – HTTP port for the auth service.
You may extend this file as the service evolves.
Generate a local RSA key pair for JWT signing:
mkdir -p configs/secrets
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out configs/secrets/auth_jwt_private.pem
openssl rsa -in configs/secrets/auth_jwt_private.pem -pubout -out configs/secrets/auth_jwt_public.pem
chmod 600 configs/secrets/auth_jwt_private.pemThe auth service signs JWTs with the private key. Other services should fetch public keys from
/auth/v0/.well-known/jwks.json and use them only to verify access tokens.
This project uses the standard userver service template Makefile.
PRESET is one of:
debug
release
debug-custom
release-custom (if you add custom presets in CMakeUserPresets.json)
Typical workflow:
# Configure CMake for debug preset
make cmake-debug
# Build the service
make build-debug
# Build and run all tests
make test-debug
The resulting binary will be in build-debug/ (for debug preset).
Running the service locally
After a successful build:
Make sure Postgres is running and accessible
Either via your local installation
Or via docker-compose up if you use Docker for infra
Run the service, for example:
./build-debug/smirkly-auth \
--config ./configs/static_config.yamlIf your static_config.yaml is using config_vars.yaml (userver-style), ensure both files are present in configs/.
PRESET is either debug, release, or if you've added custom presets in CMakeUserPresets.json, it
can also be debug-custom, release-custom.
make cmake-PRESET- run cmake configure, update cmake options and source file listsmake build-PRESET- build the servicemake test-PRESET- build the service and run all testsmake start-PRESET- build the service, start it in testsuite environment and leave it runningmake install-PRESET- build the service and install it in directory set in environmentPREFIXmakeormake all- build and run all tests indebugandreleasemodesmake format- reformat all C++ and Python sourcesmake dist-clean- clean build files and cmake cachemake docker-COMMAND- runmake COMMANDin docker environmentmake docker-clean-data- stop docker containers
Unit tests are written in C++ using userver::utest (GoogleTest-based) and live under tests/unit/.
To run them locally:
make test-debug
or explicitly:
cmake -S . -B cmake-build-debug -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build cmake-build-debug -j$(nproc)
cd cmake-build-debug
ctest --output-on-failureNew tests should be placed under tests/unit/… and will be picked up automatically by CMake if they match the configured glob (tests/unit/*.cpp).
Project documentation lives in docs/.
docs/index.html- service overview.docs/getting-started.html- local setup and development workflow.docs/api.html- Swagger UI foropenapi/auth-v0.yaml.docs/architecture.html- service architecture notes.docs/operations.html- deployment and operations checklist.
The .github/workflows/pages.yml workflow publishes the static docs site with GitHub Pages.
The original template is distributed under the Apache-2.0 License and CLA. Services based on the template may change the license and CLA.