MachineAuth is a self-hosted AI Agent Authentication SaaS platform (v2.12.61) providing OAuth 2.0-based authentication for AI agents and machine-to-machine communication.
- Backend: Go 1.21+ (module:
machineauth) - Frontend: React 18 + TypeScript + Vite + Tailwind CSS
- Database: PostgreSQL 15+ (or JSON file for development)
- SDKs:
sdk/typescript(@machineauth/sdk) andsdk/python(machineauth)
go mod download # Install dependencies
go build -o bin/server ./cmd/server # Build server
go run ./cmd/server # Run server
go test -v ./... # Run all tests
go test -v -run TestName ./path/... # Run single test
go test -v -coverprofile=cov.out ./... # Tests with coverage
golangci-lint run # Lint (requires golangci-lint)
go fmt ./... && go vet ./... # Formatcd web && npm install # Install dependencies
cd web && npm run dev # Development (port 3000)
cd web && npm run build # Production build
cd web && npm run lint # Lint
cd web && npx tsc --noEmit # TypeScript checkImports: stdlib → external → internal (use goimports)
import (
"context"
"encoding/json"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
"machineauth/internal/config"
"machineauth/internal/models"
)Naming: Packages lowercase, exported PascalCase, unexported camelCase, constants PascalCase.
Error Handling: Wrap with context using fmt.Errorf with %w:
if err != nil {
return nil, fmt.Errorf("failed to create agent: %w", err)
}HTTP Handlers: Return structured JSON, proper status codes:
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(models.AgentResponse{Agent: *agent})Types: Use precise types, pointers for optional values, embed uuid.UUID directly:
type Agent struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
}Logging: Use log.Printf with context.
Imports: Use absolute imports with @/ alias.
import { useState } from 'react';
import { AgentService } from '@/services/api';
import { Agent } from '@/types';Naming: Components PascalCase, functions camelCase, files kebab-case.
Types: Define explicit types, avoid any.
Styling: Tailwind CSS with HSL color variables.
machineauth/
├── cmd/server/main.go # Entry point
├── internal/
│ ├── config/ # Configuration
│ ├── db/ # Database layer
│ ├── handlers/ # HTTP handlers
│ ├── middleware/ # HTTP middleware
│ ├── models/ # Data models
│ └── services/ # Business logic
├── web/ # React frontend
│ └── src/
│ ├── components/ # React components
│ ├── pages/ # Page components
│ ├── services/ # API services
│ ├── types/ # TypeScript types
│ └── App.tsx
└── docker-compose.yml
| Method | Path | Description |
|---|---|---|
| POST | /oauth/token |
Get access token |
| POST | /oauth/introspect |
Validate token |
| POST | /oauth/revoke |
Revoke token |
| GET | /.well-known/jwks.json |
Public keys |
| GET | /health |
Health check |
| GET | /health/ready |
Readiness check |
| GET | /metrics |
Service metrics |
| GET | /api/agents |
List agents |
| POST | /api/agents |
Create agent |
| GET | /api/agents/:id |
Get agent |
| DELETE | /api/agents/:id |
Delete agent |
| POST | /api/agents/:id/rotate |
Rotate credentials |
| POST | /api/webhooks |
Create webhook |
| GET | /api/webhooks |
List webhooks |
| GET | /api/webhooks/:id |
Get webhook |
| PUT | /api/webhooks/:id |
Update webhook |
| DELETE | /api/webhooks/:id |
Delete webhook |
| POST | /api/webhooks/:id/test |
Test webhook |
| GET | /api/webhooks/:id/deliveries |
Delivery history |
| GET | /api/webhook-events |
List event types |
idUUID PRIMARY KEYnameVARCHAR(255) NOT NULLclient_idVARCHAR(255) UNIQUE NOT NULLclient_secret_hashVARCHAR(255) NOT NULLscopesTEXT[] DEFAULT '{}'public_keyTEXT (for DPoP/mTLS)is_activeBOOLEAN DEFAULT truecreated_atTIMESTAMPupdated_atTIMESTAMPexpires_atTIMESTAMP (optional)
idUUID PRIMARY KEYagent_idUUID REFERENCES agents(id)actionVARCHAR(100)ip_addressVARCHAR(45)user_agentTEXTcreated_atTIMESTAMP
idUUID PRIMARY KEYorganization_idVARCHAR(255)team_idVARCHAR(255)nameVARCHAR(255) NOT NULLurlTEXT NOT NULLsecretVARCHAR(255) NOT NULLeventsTEXT[] NOT NULLis_activeBOOLEAN DEFAULT truemax_retriesINTEGER DEFAULT 10retry_backoff_baseINTEGER DEFAULT 2created_atTIMESTAMPupdated_atTIMESTAMPlast_tested_atTIMESTAMP (optional)consecutive_failsINTEGER DEFAULT 0
idUUID PRIMARY KEYwebhook_config_idUUID REFERENCES webhook_configs(id)eventVARCHAR(100)payloadTEXTheadersTEXTstatusVARCHAR(50) (pending, delivered, failed, retrying, dead)attemptsINTEGER DEFAULT 0last_attempt_atTIMESTAMP (optional)last_errorTEXTnext_retry_atTIMESTAMP (optional)created_atTIMESTAMP
PORT=8080
ENV=development
DATABASE_URL=postgresql://user:pass@localhost:5432/agentauth
# Dev fallback: DATABASE_URL=json:machineauth.json
JWT_SIGNING_ALGORITHM=RS256
JWT_KEY_ID=key-1
JWT_ACCESS_TOKEN_EXPIRY=3600
ALLOWED_ORIGINS=http://localhost:3000
# Admin
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=changeme
# Webhooks
WEBHOOK_WORKER_COUNT=3
WEBHOOK_MAX_RETRIES=10
WEBHOOK_TIMEOUT_SECS=10- Frontend proxies
/api,/oauth,/.well-known,/health,/metricstolocalhost:8081 - Use
@/for absolute imports (maps to./src/) - Admin credentials:
admin@example.com/changeme(change before deployment) - Primary Go entry:
go run ./cmd/server(port 8080)
- Handlers: HTTP request/response handling, validation (see
internal/handlers/agents.go) - Services: Business logic, orchestration (see
internal/services/) - Models: API request/response types, JSON serialization (see
internal/models/models.go) - DB: Storage abstraction;
db.Connectreturns either PostgreSQL orJSONDBbased onDATABASE_URLprefix (seeinternal/db/db.go) - Backend uses
snake_caseJSON (e.g.,client_id,expires_at);ClientSecretHashtaggedjson:"-"(never serialized) - Frontend: React hooks for state,
react-hook-formfor forms,sonnerfor toasts,axiosfor API calls - Frontend API base URL from
VITE_API_URLenv var; falls back to production URL — set it tohttp://localhost:8081locally - Router registration:
cmd/server/main.gowires all routes manually ontohttp.NewServeMux; middleware (JWTAuth,AdminAuth) wraps handlers via closures middleware.AgentIDKeycontext key carriesuuid.UUID; retrieve withmiddleware.GetAgentIDFromContext(ctx)- Webhook system:
services.DeliveryWorkergoroutine pool dispatches deliveries;AuditService.SetWebhookServiceinjects webhook triggering into audit events - Version string lives in
cmd/server/main.goroot handler response ("version":"2.12.61")