A comprehensive authentication microservice for the TreeTracker system that integrates with Keycloak for identity management and Hyperledger Fabric for blockchain-based user enrollment.
- Keycloak Integration: Complete user authentication and authorization
- Hyperledger Fabric Integration: Automatic user enrollment in blockchain network
- JWT Token Management: Secure token-based authentication
- Role-Based Access Control (RBAC): Fine-grained permission management
- RESTful API: Clean and well-documented API endpoints
- Kubernetes Ready: Production-ready deployment manifests
- Security: Rate limiting, CORS, helmet, and input validation
- Logging: Structured logging with Winston
- Health Checks: Built-in health check endpoints
- Node.js 20.x or higher
- Keycloak instance running
- Hyperledger Fabric network deployed
- Kubernetes cluster (for production deployment)
cd treetracker-auth-service
npm installCopy the example environment file and configure:
cp .env.example .envEdit .env with your configuration:
# Keycloak Configuration
KEYCLOAK_URL=http://your-keycloak-url:8080
KEYCLOAK_REALM=treetracker
KEYCLOAK_CLIENT_ID=treetracker-auth
KEYCLOAK_CLIENT_SECRET=your-client-secret
# Fabric Configuration
FABRIC_PEER_ENDPOINT=peer0.greenstand.treetracker.svc.cluster.local:7051
FABRIC_CA_URL=https://ca.greenstand.treetracker.svc.cluster.local:7054
# ... other Fabric settingsnpm run devThe service will start on http://localhost:3000
npm run buildnpm starthttp://localhost:3000/api/v1
GET /healthResponse:
{
"success": true,
"message": "TreeTracker Auth Service is running",
"timestamp": "2025-01-15T10:30:00.000Z"
}POST /auth/registerRequest Body:
{
"username": "johndoe",
"email": "john@example.com",
"password": "SecurePass123!",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+1234567890",
"region": "North America",
"projectCode": "NA-2025-001"
}Response:
{
"success": true,
"message": "User registered successfully",
"data": {
"userId": "uuid-here",
"username": "johndoe",
"email": "john@example.com"
}
}POST /auth/loginRequest Body:
{
"username": "johndoe",
"password": "SecurePass123!"
}Response:
{
"success": true,
"message": "Login successful",
"data": {
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600,
"tokenType": "Bearer",
"user": {
"id": "uuid-here",
"username": "johndoe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"fabricEnrolled": true
}
}
}POST /auth/refreshRequest Body:
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Response:
{
"success": true,
"message": "Token refreshed successfully",
"data": {
"accessToken": "new-access-token",
"refreshToken": "new-refresh-token",
"expiresIn": 3600,
"tokenType": "Bearer"
}
}POST /auth/logoutRequest Body:
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Response:
{
"success": true,
"message": "Logout successful"
}GET /auth/profile
Authorization: Bearer {access_token}Response:
{
"success": true,
"data": {
"id": "uuid-here",
"username": "johndoe",
"email": "john@example.com",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+1234567890",
"region": "North America",
"projectCode": "NA-2025-001",
"fabricEnrolled": true,
"emailVerified": false,
"enabled": true
}
}PUT /auth/profile
Authorization: Bearer {access_token}Request Body:
{
"firstName": "John",
"lastName": "Smith",
"phoneNumber": "+1234567890",
"region": "North America"
}Response:
{
"success": true,
"message": "Profile updated successfully"
}POST /auth/fabric/enroll
Authorization: Bearer {access_token}Response:
{
"success": true,
"message": "Successfully enrolled in Fabric network"
}GET /auth/fabric/identity
Authorization: Bearer {access_token}Response:
{
"success": true,
"data": {
"enrolled": true,
"mspId": "GreenstandMSP"
}
}All protected endpoints require a Bearer token in the Authorization header:
Authorization: Bearer {access_token}
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TreeTracker Web App β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Authentication Microservice β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Express β β Keycloak β β Fabric β β
β β Server ββββ Service ββββ Service β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββ ββββββββββββ ββββββββββββ
β API β β Keycloak β β Fabric β
β Gateway β β Server β β Network β
ββββββββββββ ββββββββββββ ββββββββββββ
docker build -t treetracker/auth-service:latest .docker run -d \
--name treetracker-auth \
-p 3000:3000 \
--env-file .env \
treetracker/auth-service:latestkubectl create namespace treetracker# Edit secrets.yaml with your actual credentials
kubectl apply -f k8s/secrets.yamlkubectl apply -f k8s/deployment.yaml# Edit ingress.yaml with your domain
kubectl apply -f k8s/ingress.yamlkubectl get pods -n treetracker
kubectl logs -f deployment/treetracker-auth-service -n treetracker| Variable | Description | Default |
|---|---|---|
NODE_ENV |
Environment (development/production) | development |
PORT |
Server port | 3000 |
KEYCLOAK_URL |
Keycloak server URL | http://localhost:8080 |
KEYCLOAK_REALM |
Keycloak realm name | treetracker |
KEYCLOAK_CLIENT_ID |
Keycloak client ID | treetracker-auth |
KEYCLOAK_CLIENT_SECRET |
Keycloak client secret | - |
FABRIC_PEER_ENDPOINT |
Fabric peer endpoint | localhost:7051 |
FABRIC_CA_URL |
Fabric CA URL | https://localhost:7054 |
JWT_SECRET |
JWT signing secret | - |
CORS_ORIGIN |
Allowed CORS origins | http://localhost:3001 |
- Create Realm: Create a realm named
treetracker - Create Client: Create a client with ID
treetracker-auth - Configure Client:
- Access Type: confidential
- Service Accounts Enabled: ON
- Authorization Enabled: ON
- Create Roles: Create roles like
planter,verifier,admin - Get Client Secret: Copy from Credentials tab
Ensure your Fabric network has:
- CA server running
- Peer nodes accessible
- Channel created
- Chaincode deployed
- Admin user enrolled
npm testnpm run test:watchnpm run test:coveragecurl http://localhost:3000/api/v1/health# Development
npm run dev
# Production
tail -f logs/combined.log
tail -f logs/error.logkubectl logs -f deployment/treetracker-auth-service -n treetracker- Rate Limiting: 100 requests per 15 minutes per IP
- Helmet: Security headers enabled
- CORS: Configurable origin whitelist
- Input Validation: Express-validator for all inputs
- JWT: Secure token-based authentication
- HTTPS: Enforced in production
- Secrets: Stored in Kubernetes secrets
All errors return a consistent format:
{
"success": false,
"error": "Error message here",
"details": [] // Optional validation details
}200- Success201- Created400- Bad Request401- Unauthorized403- Forbidden404- Not Found500- Internal Server Error
Logs are structured JSON format:
{
"timestamp": "2025-01-15T10:30:00.000Z",
"level": "info",
"message": "User logged in successfully",
"username": "johndoe"
}In treetracker-web/.env.local:
NEXT_PUBLIC_API_URL=https://auth.treetracker.example.com/api/v1The web app's API service (lib/api.ts) is already configured to work with this auth service.
- User registers/logs in through web app
- Web app receives JWT tokens
- Tokens stored in localStorage
- All API requests include Bearer token
- Auth service validates token with Keycloak
- Protected routes check Fabric enrollment
- Fork the repository
- Create a feature branch
- Make your changes
- Write tests
- Submit a pull request
For issues and questions:
- Create an issue in the repository
- Contact the TreeTracker team
- Check documentation
- Add OAuth2 providers (Google, GitHub)
- Implement 2FA
- Add email verification
- Password reset functionality
- User activity logging
- Advanced RBAC policies
- API rate limiting per user
- Metrics and monitoring dashboard
Built with π³ for sustainable reforestation
TreeTracker Authentication Service - Securing the future of reforestation
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Author: imos64
Maintainer: Imonikhe Aikoroje