Authentication API

The Authentication API manages user credentials, tokens, and device authentication for Bootspring CLI and services.

Overview#

Bootspring supports two authentication methods:

  1. JWT Token Authentication - Session-based authentication with refresh tokens
  2. API Key Authentication - Long-lived keys for programmatic access

All credentials are stored securely in ~/.bootspring/ with AES-256 encryption.

REST API Endpoints#

Login#

POST /api/v1/auth/login

Authenticate a user and receive access tokens.

Request Body:

1{ 2 "email": "user@example.com", 3 "password": "your-password", 4 "deviceContext": { 5 "deviceId": "device-uuid", 6 "platform": "darwin", 7 "arch": "arm64" 8 } 9}

Response:

1{ 2 "data": { 3 "token": "eyJhbGciOiJIUzI1NiIs...", 4 "refreshToken": "eyJhbGciOiJIUzI1NiIs...", 5 "expiresIn": "15m", 6 "user": { 7 "id": "user_123", 8 "email": "user@example.com", 9 "tier": "pro" 10 } 11 }, 12 "meta": { 13 "requestId": "req_abc123" 14 } 15}

Register#

POST /api/v1/auth/register

Create a new user account.

Request Body:

{ "email": "user@example.com", "password": "secure-password", "name": "John Doe" }

Response:

1{ 2 "data": { 3 "token": "eyJhbGciOiJIUzI1NiIs...", 4 "refreshToken": "eyJhbGciOiJIUzI1NiIs...", 5 "expiresIn": "15m", 6 "user": { 7 "id": "user_123", 8 "email": "user@example.com", 9 "tier": "free" 10 } 11 }, 12 "meta": { 13 "requestId": "req_abc123" 14 } 15}

Get Current User#

GET /api/v1/auth/me

Get the currently authenticated user's profile.

Headers:

Authorization: Bearer YOUR_TOKEN

Response:

1{ 2 "data": { 3 "id": "user_123", 4 "email": "user@example.com", 5 "name": "John Doe", 6 "tier": "pro", 7 "createdAt": "2024-01-15T10:30:00Z" 8 }, 9 "meta": { 10 "requestId": "req_abc123" 11 } 12}

Refresh Token#

POST /api/v1/auth/refresh

Refresh an expired access token.

Request Body:

{ "refreshToken": "eyJhbGciOiJIUzI1NiIs..." }

Response:

1{ 2 "data": { 3 "token": "eyJhbGciOiJIUzI1NiIs...", 4 "refreshToken": "eyJhbGciOiJIUzI1NiIs...", 5 "expiresIn": "15m" 6 }, 7 "meta": { 8 "requestId": "req_abc123" 9 } 10}

JavaScript/Node.js API#

Module Import#

const auth = require('bootspring/core/auth');

Credential Management#

getCredentials()#

Get stored credentials (decrypted).

const credentials = auth.getCredentials(); // Returns: { token, refreshToken, expiresAt, user, apiKey }

saveCredentials(credentials)#

Save credentials with encryption.

1auth.saveCredentials({ 2 token: 'jwt-token', 3 refreshToken: 'refresh-token', 4 expiresAt: '2024-01-15T12:00:00Z', 5 user: { id: 'user_123', email: 'user@example.com', tier: 'pro' } 6});

clearCredentials()#

Clear all stored credentials (logout).

auth.clearCredentials();

Token Management#

getToken()#

Get the current JWT token if valid.

Returns: Token string or null if expired/not present.

const token = auth.getToken(); if (token) { // Use token for API requests }

getApiKey()#

Get the stored API key.

const apiKey = auth.getApiKey();

getRefreshToken()#

Get the refresh token.

const refreshToken = auth.getRefreshToken();

isApiKeyAuth()#

Check if using API key authentication.

if (auth.isApiKeyAuth()) { console.log('Using API key authentication'); }

Authentication State#

isAuthenticated()#

Check if user is authenticated (valid token or API key).

if (auth.isAuthenticated()) { console.log('User is logged in'); } else { console.log('Please log in'); }

getUser()#

Get the current user's profile.

const user = auth.getUser(); // Returns: { id, email, tier, ... } or null

getTier()#

Get the user's subscription tier.

const tier = auth.getTier(); // Returns: 'free', 'pro', 'team', or 'enterprise'

Login/Logout#

login(response)#

Save login response from JWT authentication.

1auth.login({ 2 token: 'jwt-token', 3 refreshToken: 'refresh-token', 4 expiresIn: '15m', 5 user: { id: 'user_123', email: 'user@example.com', tier: 'pro' } 6});

loginWithApiKey(apiKey, user)#

Save API key authentication.

auth.loginWithApiKey('bs_live_abc123...', { id: 'user_123', email: 'user@example.com', tier: 'pro' });

updateTokens(response)#

Update tokens after refresh.

auth.updateTokens({ token: 'new-jwt-token', refreshToken: 'new-refresh-token', expiresIn: '15m' });

logout()#

Clear all credentials and log out.

auth.logout();

Device Fingerprinting#

generateDeviceFingerprint()#

Generate a unique device fingerprint based on machine characteristics.

const fingerprint = auth.generateDeviceFingerprint(); // Returns: SHA-256 hash of device characteristics

getDeviceInfo()#

Get or create persistent device information.

Returns: Device info object that persists across sessions.

1const deviceInfo = auth.getDeviceInfo(); 2// Returns: 3// { 4// deviceId: 'uuid', 5// fingerprint: 'sha256-hash', 6// createdAt: '2024-01-15T10:30:00Z', 7// platform: 'darwin', 8// arch: 'arm64', 9// hostname: 'my-macbook' 10// }

getDeviceId()#

Get just the device ID.

const deviceId = auth.getDeviceId();

getDeviceContext()#

Get full device context for authentication requests.

1const context = auth.getDeviceContext(); 2// Returns: 3// { 4// deviceId: 'uuid', 5// platform: 'darwin', 6// arch: 'arm64', 7// hostname: 'my-macbook', 8// cliVersion: '1.2.0', 9// nodeVersion: 'v20.10.0', 10// timezone: 'America/New_York' 11// }

clearDeviceInfo()#

Clear device info (for testing or reset).

auth.clearDeviceInfo();

Configuration#

getConfig()#

Get global Bootspring configuration.

const config = auth.getConfig();

saveConfig(config)#

Save global configuration.

auth.saveConfig({ defaultProject: '/path/to/project', theme: 'dark' });

getCredentialsPath()#

Get the path to the credentials file.

const path = auth.getCredentialsPath(); // Returns: '/Users/username/.bootspring/credentials.json'

Constants#

BOOTSPRING_DIR#

Path to Bootspring's config directory.

const { BOOTSPRING_DIR } = require('bootspring/core/auth'); // Returns: '/Users/username/.bootspring'

File Storage#

Bootspring stores authentication data in the following files:

FilePurpose
~/.bootspring/credentials.jsonEncrypted user credentials
~/.bootspring/config.jsonGlobal configuration
~/.bootspring/device.jsonDevice fingerprint and ID

All credential files are created with 0600 permissions (owner read/write only).

Security Features#

Credential Encryption#

Credentials are encrypted using AES-256-CBC with a machine-derived key:

  • Key is derived from hostname and username
  • Each credential file has a unique initialization vector (IV)
  • Encryption is transparent - decryption happens automatically on read

Device Fingerprinting#

Device fingerprinting provides:

  • Unique device identification for multi-device management
  • Detection of credential copying between machines
  • Session security enhancement

Fingerprint components:

  • Hostname
  • Username
  • Platform and architecture
  • CPU model
  • Home directory path
  • Network interface MAC addresses

Error Handling#

Invalid Credentials#

1{ 2 "error": { 3 "code": "UNAUTHORIZED", 4 "message": "Invalid email or password" 5 } 6}

Expired Token#

1{ 2 "error": { 3 "code": "UNAUTHORIZED", 4 "message": "Token has expired" 5 } 6}

Invalid Refresh Token#

1{ 2 "error": { 3 "code": "UNAUTHORIZED", 4 "message": "Invalid or expired refresh token" 5 } 6}

Best Practices#

  1. Use API keys for automation: For CI/CD and scripts, prefer API keys over JWT tokens
  2. Rotate API keys regularly: Generate new API keys periodically for security
  3. Don't share credentials: Each team member should have their own credentials
  4. Use environment variables: Store API keys in environment variables, not in code
  5. Handle token refresh: Implement automatic token refresh in long-running applications

CLI Commands#

1# Login with email/password 2bootspring auth login 3 4# Login with API key 5bootspring auth login --api-key YOUR_API_KEY 6 7# Check authentication status 8bootspring auth status 9 10# Logout 11bootspring auth logout 12 13# Show credentials file location 14bootspring auth path