Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

AccessCore Service

API Key Management System built with NestJS - A secure and scalable solution for managing API keys with authentication, rotation, and access control.

πŸš€ Features

  • βœ… User authentication with JWT
  • βœ… API key generation with cryptographic security
  • βœ… API key rotation and revocation
  • βœ… Maximum 3 active keys per user
  • βœ… Automatic key expiration (1 year default)
  • βœ… Access logging (bonus feature)
  • βœ… Rate limiting per API key (bonus feature)
  • βœ… 74%+ test coverage

πŸ“‹ Tech Stack

  • Framework: NestJS 9.x
  • Runtime: Node.js 24.x
  • Language: TypeScript 4.x
  • Database: MongoDB Atlas (Cloud)
  • Authentication: JWT (JSON Web Tokens)
  • Password Hashing: bcrypt
  • Testing: Jest + Supertest
  • Containerization: Docker

πŸ“¦ Installation

Prerequisites

  • Node.js 24+ installed
  • MongoDB Atlas account (or local MongoDB 7+)
  • Yarn package manager
  • Docker (optional, for containerization)

Steps

  1. Clone the repository

    git clone <repository-url>
    cd accesscore_service
  2. Install dependencies

    yarn install
  3. Set up environment variables

    Create a .env file in the root directory:

    # App
    NODE_ENV=development
    PORT=3000
    
    # Database (MongoDB Atlas)
    MONGODB_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/accesscore?retryWrites=true&w=majority
    
    # JWT
    JWT_SECRET=your-super-secret-jwt-key-change-in-production
    JWT_EXPIRATION=24h
    
    # API Key Settings
    API_KEY_MAX_ACTIVE=3
    API_KEY_DEFAULT_EXPIRATION_DAYS=365

    Note: Replace <username>, <password>, and <cluster> with your MongoDB Atlas credentials.

  4. Run database migrations

    npx migrate-mongo up

πŸƒ Running the Application

Development Mode

yarn start:dev

Server runs on: http://localhost:3000

Production Mode

yarn build
yarn start:prod

Watch Mode

yarn start:debug

Docker (Containerized)

# Build Docker image
docker build -t accesscore-service .

# Run container
docker run -p 3000:3000 --env-file .env accesscore-service

πŸ§ͺ Testing

Run all tests

yarn test

Run tests with coverage

yarn test:cov

Current coverage: 74.44%

Run E2E tests

yarn test:e2e

πŸ“š API Documentation

Postman Collection

Import the Postman collection for complete API documentation with examples:

File: AccessCore_API.postman_collection.json

Import Steps:

  1. Open Postman
  2. Click "Import" button
  3. Select the JSON file
  4. Collection will appear with all endpoints

API Endpoints

Authentication

  • POST /auth/register - Register a new user
  • POST /auth/login - Login and receive JWT token

API Keys (Protected - JWT Required)

  • POST /api-keys - Generate new API key
  • GET /api-keys - List all API keys
  • DELETE /api-keys/:id - Revoke an API key
  • POST /api-keys/:id/rotate - Rotate an API key

Access Logs (Protected - JWT Required)

  • GET /access-logs - View audit logs of all API key operations

πŸš€ Rate Limiting Implementation

Rate limiting guards are implemented and ready to use:

Guards Available:

  • ApiKeyAuthGuard - Validates API keys from x-api-key or Authorization: Bearer headers
  • ApiKeyRateLimitGuard - Enforces per-API-key rate limits (configurable, default 100 req/hour)

How to Use:

import { UseGuards } from '@nestjs/common';
import { ApiKeyAuthGuard } from './common/guards/api-key-auth.guard';
import { ApiKeyRateLimitGuard } from './common/guards/api-key-rate-limit.guard';

@Get('your-endpoint')
@UseGuards(ApiKeyAuthGuard, ApiKeyRateLimitGuard)
yourMethod() {
  return { data: 'protected' };
}

Features:

  • Per-API-key rate limiting (not global)
  • Configurable limits when generating keys (1-10000 requests/hour)
  • Automatic request tracking via access logs
  • Returns HTTP 429 when limit exceeded
  • Supports both x-api-key and Authorization: Bearer formats

Quick Start Example

  1. Register a user

    curl -X POST http://localhost:3000/auth/register \
      -H "Content-Type: application/json" \
      -d '{
        "email": "user@example.com",
        "password": "Password123!"
      }'
  2. Login

    curl -X POST http://localhost:3000/auth/login \
      -H "Content-Type: application/json" \
      -d '{
        "email": "user@example.com",
        "password": "Password123!"
      }'

    Save the accessToken from response.

  3. Generate API Key

    curl -X POST http://localhost:3000/api-keys \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
      -d '{
        "name": "Production API Key",
        "rateLimit": 100
      }'

    Save the key from response. This key can be used by external apps to access protected endpoints.

πŸ”’ Security Features

  • Password Requirements: Minimum 8 characters with uppercase, lowercase, number, and special character
  • API Key Format: ak_live_ prefix + 64 character hex string
  • Hashing: bcrypt with 10 salt rounds for passwords and API keys
  • JWT Expiration: 24 hours (configurable)
  • Key Expiration: 1 year default (configurable)
  • Max Active Keys: 3 per user (configurable)
  • Rate Limiting: Configurable per API key (default: 100 requests/hour)
  • Authentication: Supports both x-api-key header and Authorization: Bearer format
  • CORS: Configurable origins for production, open in development

πŸ—„οΈ Database Schema

Users Collection

{
  _id: ObjectId
  email: string (unique)
  password: string (hashed)
  createdAt: Date
  updatedAt: Date
}

API Keys Collection

{
  _id: ObjectId
  userId: ObjectId (ref: User)
  key: string (hashed)
  prefix: string (visible, e.g., "ak_live_abc123")
  name: string
  status: "ACTIVE" | "REVOKED" | "EXPIRED"
  rateLimit: number (requests per hour, default: 100)
  expiresAt: Date
  lastUsedAt: Date
  revokedAt: Date
  createdAt: Date
  updatedAt: Date
}

Access Logs Collection (Bonus)

{
  _id: ObjectId
  apiKeyId: ObjectId (ref: ApiKey)
  userId: ObjectId (ref: User)
  endpoint: string
  method: string
  statusCode: number
  ipAddress: string
  userAgent: string
  timestamp: Date
}

πŸ“ Project Structure

src/
β”œβ”€β”€ modules/
β”‚   β”œβ”€β”€ auth/              # Authentication module
β”‚   β”œβ”€β”€ api-keys/          # API key management
β”‚   └── access-logs/       # Access logging (bonus)
β”œβ”€β”€ common/
β”‚   β”œβ”€β”€ constants/         # App constants
β”‚   β”œβ”€β”€ decorators/        # Custom decorators
β”‚   β”œβ”€β”€ interceptors/      # Logging interceptor
β”‚   └── utils/             # Crypto & hash utilities
β”œβ”€β”€ config/                # Configuration files
β”œβ”€β”€ app.module.ts
└── main.ts

test/
β”œβ”€β”€ *.spec.ts             # Unit tests
└── *.e2e-spec.ts         # E2E tests

migrations/               # Database migrations

πŸš€ Deployment

Deployment URL

Production: https://sxz4fpw7u6.us-east-1.awsapprunner.com

Docker Deployment

The application is containerized using Docker for easy deployment.

Build and run locally:

# Build image
docker build -t accesscore-service .

# Run container
docker run -p 3000:3000 --env-file .env accesscore-service

Docker Compose (with MongoDB):

docker-compose up -d

AWS Deployment (Recommended)

Platform Options:

  • AWS ECS Fargate (Serverless containers)
  • AWS EC2 (Traditional instances)
  • AWS App Runner (Simplified container deployment)

Database:

  • MongoDB Atlas (Cloud-managed)
  • AWS DocumentDB (AWS-managed MongoDB-compatible)

Deployment Steps:

  1. Build Docker image
  2. Push to AWS ECR (Elastic Container Registry)
  3. Create ECS task definition
  4. Deploy to ECS Fargate/EC2
  5. Configure Application Load Balancer
  6. Set up CloudWatch for logging and monitoring

MongoDB Atlas Setup

  1. Create a cluster on MongoDB Atlas
  2. Create a database user with read/write permissions
  3. Whitelist IP addresses:
    • For development: Your local IP
    • For production: 0.0.0.0/0 or specific AWS IPs
  4. Get connection string from Atlas dashboard
  5. Add connection string to .env file

Connection String Format:

mongodb+srv://<username>:<password>@<cluster>.mongodb.net/accesscore?retryWrites=true&w=majority

πŸ”§ Environment Variables Reference

Variable Description Default Required
NODE_ENV Environment mode development No
PORT Server port 3000 No
MONGODB_URI MongoDB Atlas connection string - Yes
JWT_SECRET JWT signing secret - Yes
JWT_EXPIRATION JWT token expiration 24h No
API_KEY_MAX_ACTIVE Max active keys per user 3 No
API_KEY_DEFAULT_EXPIRATION_DAYS Default key expiration 365 No
ALLOWED_ORIGINS CORS allowed origins (production) - No

πŸ“Š Test Coverage

Current test coverage: 74.44%

πŸš€ Rate Limiting

How It Works

  1. Per-API-Key Limits: Each API key has its own rate limit (default: 100 requests/hour)
  2. Configurable: Set custom rate limits when generating API keys (1-10000 requests/hour)
  3. Automatic Tracking: All API key requests are logged in the access logs
  4. Clear Errors: Returns HTTP 429 with descriptive message when limit exceeded

Usage

Generate API key with custom rate limit:

curl -X POST http://localhost:3000/api-keys \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My API Key",
    "rateLimit": 500
  }'

Apply guards to protect endpoints:

@Get('your-endpoint')
@UseGuards(ApiKeyAuthGuard, ApiKeyRateLimitGuard)
yourMethod() {
  return { data: 'protected' };
}

External apps access with API key:

# Using x-api-key header
curl -X GET http://localhost:3000/your-endpoint \
  -H "x-api-key: YOUR_API_KEY"

# Using Authorization Bearer format
curl -X GET http://localhost:3000/your-endpoint \
  -H "Authorization: Bearer YOUR_API_KEY"

Rate limit exceeded response:

{
  "statusCode": 429,
  "message": "Rate limit exceeded. Maximum 100 requests per hour."
}

🐳 Docker

The application includes a Dockerfile for containerization:

  • Multi-stage build for optimized image size
  • Node.js 24 Alpine base image
  • Production-ready configuration
  • Health check endpoint included

See Dockerfile for complete configuration.

βœ… Bonus Features Implemented

  1. Access Logs (Audit Trail)

    • Tracks all API key operations
    • Records endpoint, method, status code, IP, and user agent
    • Queryable by user or API key
    • Automatic logging via interceptor
  2. Rate Limiting per API Key

    • Configurable limits per API key (1-10000 requests/hour)
    • Automatic request tracking via access logs
    • Returns HTTP 429 when limit exceeded
    • Supports both x-api-key and Authorization: Bearer headers
    • Apply to any endpoint using @UseGuards(ApiKeyAuthGuard, ApiKeyRateLimitGuard)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages