π Languages: πΊπΈ English | Polski | δΈζ
AstraDesk
is an internal framework for building AI agents designed for Support and SRE/DevOps departments.
It provides a modular architecture with ready-to-use demo agents, integrations with databases, messaging systems, and DevOps tools.
The framework supports scalability, enterprise-grade security (OIDC/JWT, RBAC, mTLS via Istio), and full CI/CD automation.
- Features
- Purpose and Use Cases
- Architecture Overview
- Admin Portal
- Prerequisites
- Installation
- Configuration
- Usage
- Deployment
- CI/CD
- Monitoring and Observability
- Developer Guide
- Testing
- Security
- Roadmap
- Contributing
- License
- Contact
- AI Agents: Three ready-to-use agents:
- SupportAgent: User support with RAG over corporate documents (PDF, HTML, Markdown), dialogue memory, and ticketing tools.
- OpsAgent: SRE/DevOps automation β fetches metrics (Prometheus/Grafana), performs operational actions (e.g., restart service) with policies and auditing.
- BillingAgent: Financial operations and billing management with secure integrations.
- Modular Core: Python-based framework with tool registry, planner, memory (Redis/Postgres), RAG (pgvector), and event handling (NATS).
- Integrations:
- Java Ticket Adapter (Spring Boot WebFlux + MySQL) for enterprise ticketing systems.
- Next.js Admin Portal for agent monitoring, audit trails, and prompt testing.
- MCP Gateway: Standardized protocol for AI agent tool interactions with security, audit, and rate limiting.
- Domain Packs: Modular MCP servers for Support, Ops, Finance, and Supply Chain domains with ready-to-use tools.
- Security: OIDC/JWT authentication, per-tool RBAC, mTLS via Istio, and full action audit.
- DevOps Ready: Docker, Kubernetes (Helm), OpenShift, Terraform (AWS), Ansible/Puppet/Salt, CI/CD with Jenkins and GitLab.
- Observability: OpenTelemetry, Prometheus/Grafana/Loki/Tempo stack.
- Scalability: HPA in Helm, retries/timeouts in integrations, autoscaling in EKS.
AstraDesk is a framework for building AI agents for Support and SRE/DevOps teams.
It provides a modular core (planner, memory, RAG, tool registry) and includes ready-to-use agent examples.
- Support / Helpdesk: RAG over company documentation (procedures, FAQs, runbooks), ticket creation/update, conversation memory.
- SRE/DevOps Automation: Metric retrieval (Prometheus/Grafana), incident triage, and controlled operational actions (e.g., service restart) protected by RBAC and audited.
- Enterprise Integrations: Gateway (Python/FastAPI), Ticket Adapter (Java/WebFlux + MySQL), Admin Portal (Next.js), MCP Gateway, and data layer (Postgres/pgvector, Redis, NATS).
- Security and Compliance: OIDC/JWT, per-tool RBAC, mTLS (Istio), and complete audit trails.
- Scalable Operations: Docker/Kubernetes/OpenShift, Terraform (AWS), CI/CD (Jenkins/GitLab), observability (OpenTelemetry, Prometheus/Grafana/Loki/Tempo).
Not just a chatbot, but a framework for composing your own agents, tools, and policies with full control (no SaaS lock-in).
AstraDesk consists of several main components:
- Python API Gateway: FastAPI service handling agent requests, RAG, memory, and tools.
- Java Ticket Adapter: Reactive WebFlux service integrating with MySQL for ticketing.
- Next.js Admin Portal: Web interface for monitoring.
- MCP Gateway: Standardized protocol gateway for AI agent tool interactions with security, audit, and rate limiting.
Communication: HTTP (between components), NATS (events/audits), Redis (working memory), Postgres/pgvector (RAG/dialogues/audits), MySQL (tickets).
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AstraDesk Admin Portal - Enterprise Dashboard & Governance β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Live Demo: https://astradesk-admin-portal.vercel.app/ β
β Repository: https://github.com/SSobol77/astradesk-admin-portal β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
AstraDesk Admin Portal to enterprise-grade panel administracyjny do zarzΔ dzania agentami AI, datasetami, flow, politykami RBAC i governance operacyjnym.
| Feature | Description |
|---|---|
| π OpenAPI-First | Strictly typed from OpenAPI 3.1 spec |
| β‘ Next.js 16 + React 19 | Modern App Router architecture |
| π Type-Safe | Generated TypeScript types from OpenAPI |
| π‘ Real-Time SSE | Live streaming for run updates |
| π§ͺ Mock API Mode | Test UI without backend (dev/demo) |
| π₯ Full RBAC + Audit | Role-based access control with audit trails |
| π Intent Graph | Visual representation of agent intents |
| π Runs & Jobs | Live streaming, filters, export |
# Clone the admin panel repository
git clone https://github.com/SSobol77/astradesk-admin-portal.git
cd astradesk-admin-portal
# Install dependencies
npm install
# Copy environment file
cp .env.example .env.local
# Run development server
npm run dev# Backend API URL (required if not using mock mode)
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080/api/admin/v1
# Set to "true" to use realistic mock data instead of real API
NEXT_PUBLIC_MOCK_API=falseFor development, testing, or demos without a running backend:
- Set
NEXT_PUBLIC_MOCK_API=truein your.env.local - The app will use realistic mock data for all endpoints
- All pages will work with simulated data and network delays
- Perfect for UI development, testing, and demonstrations
Note: Mock mode returns predefined data from
lib/mock-data.ts. No actual API calls are made.
| Page | Route | Description |
|---|---|---|
| Dashboard | / |
Health, usage, recent errors |
| Agents | /agents |
CRUD, test, promote, metrics |
| Intent Graph | /intent-graph |
Read-only graph visualization |
| Flows | /flows |
Validate, dry run, logs |
| Datasets | /datasets |
Schema, embeddings, reindex |
| Tools | /tools |
Connector management |
| Secrets | /secrets |
Key rotation, disable |
| Runs & Logs | /runs |
Live streaming, filters, export |
| Jobs | /jobs |
Schedules, triggers, DLQ |
| RBAC | /rbac |
Users, roles, invites |
| Policies | /policies |
OPA policy management |
| Audit | /audit |
Immutable audit trail |
| Settings | /settings |
Platform configuration |
The app uses Bearer JWT authentication:
- Obtain a JWT token from your auth system
- The app stores it in
localStorageasastradesk_token - All API requests include
Authorization: Bearer <token>
In Mock Mode: Authentication is bypassed - no token required.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Admin Portal (Next.js) β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββββββ β
β β Sidebar β β Topbar β β Main Content β β
β β Navigation β β User/Auth β β Dynamic Pages β β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β HTTP + SSE
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β API Gateway (FastAPI) β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β β Agents β β Audit β β RBAC/Policies β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Layer | Technology |
|---|---|
| Framework | Next.js 16 App Router |
| UI Library | React 19.2, shadcn/ui |
| Language | TypeScript (generated from OpenAPI) |
| State | React Query, Zustand |
| Real-time | Server-Sent Events (SSE) |
| Styling | Tailwind CSS |
| Testing | Vitest, Playwright |
| Resource | URL |
|---|---|
| π Live Demo | https://astradesk-admin |
| π Repository | https://github.com/SSobol77/astradesk-admin-portal |
| π Documentation | https://github.com/SSobol77/astradesk-admin-portal#readme |
- Docker and Docker Compose (for local dev).
- Kubernetes with Helm (for deployment).
- AWS CLI and Terraform (for cloud setup).
- Node.js 22, JDK 21, Python 3.11 (for builds).
- Postgres 17, MySQL 8, Redis 7, NATS 2 (core services).
- Optional: Istio, cert-manager (for mTLS/TLS).
- Clone the repository:
git clone https://github.com/your-org/astradesk.git
cd astradesk
- Copy the sample configuration:
cp .env.example .env
- Edit
.env(e.g. DATABASE_URL, OIDC_ISSUER).
- Build and start:
make up
- This starts: API Gateway (8000), MCP Servers (8001-8004), Admin Portal (3000), databases and supporting services.
- Initialize Postgres (pgvector):
make migrate
- Upload documents to
./docs(e.g. .md, .txt) and initialize RAG:
make ingest
- Check health:
curl http://localhost:8000/healthz
- Admin Portal: http://localhost:3000
- MCP Servers: http://localhost:8001 (support), 8002 (ops), 8003 (finance), 8004 (supply)
- Install dependencies:
make install-deps # Python dependencies
make build-java # Java components
make build-admin # Next.js Admin Portal
- Run locally (without Docker):
- API Gateway:
make dev-server(with hot reload) - MCP Servers:
make mcp-all(starts all domain pack servers) - Admin Portal:
cd services/admin-portal && npm run dev
- Alternative development setup:
# Automated setup (recommended)
./scripts/setup-dev-environment.sh
# Or manual setup
make setup
- DATABASE_URL: PostgreSQL connection string (e.g.
postgresql://user:pass@host:5432/db). - REDIS_URL: Redis URI (e.g.
redis://host:6379/0). - NATS_URL: NATS server (e.g.
nats://host:4222). - TICKETS_BASE_URL: URL to Java adapter (e.g.
http://ticket-adapter:8081). - MYSQL_URL: MySQL JDBC (e.g.
jdbc:mysql://host:3306/db?useSSL=false). - OIDC_ISSUER: OIDC issuer (e.g.
https://your-issuer.com/). - OIDC_AUDIENCE: JWT audience.
- OIDC_JWKS_URL: JWKS URL (e.g.
https://your-issuer.com/.well-known/jwks.json).
Full list in .env.example.
- Enabled in both API Gateway and Java Adapter.
- Use Bearer token in requests:
Authorization: Bearer <token>. - Validation: issuer, audience, signature via JWKS.
- For Admin Portal: use Auth0 or a similar front-channel flow.
- Roles from JWT claims (e.g.
"roles": ["sre"]). - Tools (e.g. restart_service) validate via
require_role(claims, "sre"). - Customize in
runtime/policy.pyand tool definitions (e.g.REQUIRED_ROLE_RESTART).
Call the API:
curl -X POST http://localhost:8080/v1/agents/run \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-jwt-token>" \
-d '{"agent": "support", "input": "Create a ticket for a network incident", "meta": {"user": "alice"}}'- Response: JSON with output, reasoning_trace_id, invoked_tools.
- Available agents:
support,ops,billing - Demo queries:
./scripts/demo_queries.sh.
- Supported formats: .md, .txt (extendable to PDF/HTML).
- Run:
make ingest(source:./docs).
- Tool registry:
registry.pyβ add new ones viaregister(name, async_fn). - Examples: create_ticket (proxy to Java), get_metrics (Prometheus stub), restart_service (RBAC-protected).
- MCP Gateway: Standardized protocol for AI agent tool interactions with built-in security, audit, and rate limiting. See MCP documentation for implementation details.
-
Build and push images (use CI).
-
Install chart:
helm upgrade --install astradesk deploy/chart -f deploy/chart/values.yaml \ --set image.tag=0.3.0 \ --set autoscaling.enabled=true
- HPA: scales when CPU >60%.
- Process template:
oc process -f deploy/openshift/astradesk-template.yaml -p TAG=0.3.0 | oc apply -f --
Initialize:
cd infra terraform init terraform apply -var="region=us-east-1" -var="project=astradesk"
- Creates: VPC, EKS, RDS (Postgres/MySQL), S3.
- Ansible:
ansible-playbook -i ansible/inventories/dev/hosts.ini ansible/roles/astradesk_docker/main.yml. - Puppet:
puppet apply puppet/manifests/astradesk.pp. - Salt:
salt '*' state.apply astradesk.
- Create namespace:
kubectl apply -f deploy/istio/00-namespace.yaml. - Enable mTLS:
kubectl apply -f deploy/istio/10-peer-authentication.yaml(and the rest in deploy/istio/). - Gateway: HTTPS on port 443 with cert-manager.
- Run pipeline:
Jenkinsfilebuilds/tests/pushes images, deploys via Helm.
.gitlab-ci.yml: stages for build/test/docker/deploy (manual).
(Prometheus, Grafana, OpenTelemetry)
This section explains how to enable full observability for the AstraDesk platform using Prometheus (metrics), Grafana (dashboards), and OpenTelemetry (instrumentation).
- Collect metrics from the Python API Gateway (
/metrics) and the Java Ticket Adapter (/actuator/prometheus). - Get a quick health view in Grafana.
- Alerting (e.g., high 5xx error rate) in Prometheus.
Below is a minimal snippet to add Prometheus + Grafana services to docker-compose.yml.
Note: We assume
apiandticket-adapterservices run with:api:8080,ticket-adapter:8081.
services:
# --- Observability stack ---
prometheus:
image: prom/prometheus:latest
container_name: astradesk-prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.enable-lifecycle" # allows hot-reload of the config
volumes:
- ./dev/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
ports:
- "9090:9090"
restart: unless-stopped
depends_on:
- api
- ticket-adapter
grafana:
image: grafana/grafana:latest
container_name: astradesk-grafana
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_DEFAULT_THEME=dark
volumes:
- grafana-data:/var/lib/grafana
# (optional) automatic provisioning for data sources / dashboards:
# - ./dev/grafana/provisioning:/etc/grafana/provisioning:ro
ports:
- "3000:3000"
restart: unless-stopped
depends_on:
- prometheus
volumes:
prometheus-data:
grafana-data:dev/prometheus/prometheus.yml
Create dev/prometheus/prometheus.yml with the following content:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_timeout: 10s
# optional: external_labels: { env: "dev" }
scrape_configs:
# FastAPI Gateway (Python)
- job_name: "api"
metrics_path: /metrics
static_configs:
- targets: ["api:8080"]
# Java Ticket Adapter (Spring Boot + Micrometer)
- job_name: "ticket-adapter"
metrics_path: /actuator/prometheus
static_configs:
- targets: ["ticket-adapter:8081"]
# (optional) NATS Exporter
# - job_name: "nats"
# static_configs:
# - targets: ["nats-exporter:7777"]
rule_files:
- /etc/prometheus/alerts.yml(Optional) Add dev/prometheus/alerts.yml and mount it similarly into the container (e.g., via an extra volume or fold it into prometheus.yml).
Sample alert rules:
groups:
- name: astradesk-alerts
rules:
- alert: HighErrorRate_API
expr: |
rate(http_requests_total{job="api",status=~"5.."}[5m])
/
rate(http_requests_total{job="api"}[5m]) > 0.05
for: 10m
labels:
severity: warning
annotations:
summary: "API high 5xx error rate (>5% for 10m)"
description: "Investigate FastAPI gateway logs and upstream dependencies."
- alert: TicketAdapterDown
expr: up{job="ticket-adapter"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Ticket Adapter is down"
description: "Spring service not responding on /actuator/prometheus."Reload configuration without restart:
curl -X POST http://localhost:9090/-/reload
The simplest way to expose /metrics is with prometheus_client:
# src/gateway/observability.py
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
from starlette.responses import Response
from fastapi import APIRouter, Request
import time
router = APIRouter()
REQUEST_COUNT = Counter(
"http_requests_total",
"Total HTTP requests",
["method", "path", "status"]
)
REQUEST_LATENCY = Histogram(
"http_request_duration_seconds",
"HTTP request latency",
["method", "path"]
)
@router.get("/metrics")
def metrics():
# Expose Prometheus metrics in plaintext format
return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)
# (optional) simple middleware for latency and counts
async def metrics_middleware(request: Request, call_next):
start = time.perf_counter()
response = await call_next(request)
elapsed = time.perf_counter() - start
path = request.url.path
method = request.method
REQUEST_LATENCY.labels(method=method, path=path).observe(elapsed)
REQUEST_COUNT.labels(method=method, path=path, status=str(response.status_code)).inc()
return responseRegister in main.py:
from fastapi import FastAPI
from src.gateway.observability import router as metrics_router, metrics_middleware
app = FastAPI()
app.middleware("http")(metrics_middleware)
app.include_router(metrics_router, tags=["observability"])Alternative (recommended): use OpenTelemetry + an
otlpexporter, then scrape metrics via otel-collector β Prometheus. This gives you unified metrics, traces, and logs.
application.yml:
management:
endpoints:
web:
exposure:
include: health, prometheus
endpoint:
prometheus:
enabled: true
metrics:
tags:
application: astradesk-ticket-adapter
observations:
key-values:
env: devMicrometer Prometheus dependency:
<!-- pom.xml -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>After startup, the endpoint is available at:
http://localhost:8081/actuator/prometheus (or ticket-adapter:8081 in Docker).
After Grafana starts (http://localhost:3000, default admin/admin):
-
Add data source β Prometheus URL:
http://prometheus:9090(inside Docker Compose network) orhttp://localhost:9090(if adding from your host). -
Import a dashboard (e.g., βPrometheus / Overviewβ or your custom one). You can also keep descriptors in the repo (
grafana/dashboard-astradesk.json) and enable provisioning:dev/grafana/provisioning/datasources/prometheus.yaml dev/grafana/provisioning/dashboards/dashboards.yaml grafana/dashboard-astradesk.json
Example data source (provisioning):
# dev/grafana/provisioning/datasources/prometheus.yaml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: trueExample dashboards provider:
# dev/grafana/provisioning/dashboards/dashboards.yaml
apiVersion: 1
providers:
- name: "AstraDesk"
orgId: 1
folder: "AstraDesk"
type: file
options:
path: /var/lib/grafana/dashboardsAdd these shortcuts to Makefile to speed up your workflow:
.PHONY: up-observability down-observability logs-prometheus logs-grafana
up-observability:
\tdocker compose up -d prometheus grafana
down-observability:
\tdocker compose rm -sfv prometheus grafana
logs-prometheus:
\tdocker logs -f astradesk-prometheus
logs-grafana:
\tdocker logs -f astradesk-grafana-
Prometheus UI: http://localhost:9090
- Check that
apiandticket-adapterjobs are UP (Status β Targets).
- Check that
-
Grafana UI: http://localhost:3000
- Connect the Prometheus data source, import a dashboard, and watch key metrics (latency, request count, 5xx errors).
-
Quick test:
curl -s http://localhost:8080/metrics | head curl -s http://localhost:8081/actuator/prometheus | head
If the endpoints donβt return metrics, make sure:
- the paths (
/metrics,/actuator/prometheus) are enabled,- services are reachable by the Compose network names
api/ticket-adapter,prometheus.ymlpoints at the correcttargets.
This section provides practical instructions and answers to common questions to help you start working with the project quickly.
Before starting, ensure you have:
- Docker and Docker Compose (Docker Desktop recommended).
- Git, make, and Node.js (v22+) installed locally.
Preparation steps (run once):
-
Clone the repository:
git clone https://github.com/your-org/astradesk.git cd astradesk -
Copy configuration file:
cp .env.example .env
-
Generate
package-lock.json: Required for building the Admin Portal Docker image.cd services/admin-portal && npm install && cd ../..
You can choose between two modes depending on your needs.
Runs the entire application (all microservices) inside Docker containers. Ideal for integration testing and production-like environments.
-
To start:
make up
(Alternatively:
docker compose up --build -d) -
To stop and clean up:
make down
(Alternatively:
docker compose down -v) -
Available services:
- API Gateway:
http://localhost:8080 - Admin Portal:
http://localhost:3000 - Ticket Adapter:
http://localhost:8081
- API Gateway:
Runs only external dependencies (databases, NATS, etc.) in Docker, while the main Python API runs locally. Ideal for fast development and debugging with instant reloads.
-
Step 1: Start dependencies in Docker (in one terminal):
make up-deps
(Alternatively:
docker compose up -d db mysql redis nats ticket-adapter) -
Step 2: Run the API locally (in another terminal):
make run-local
(Alternatively:
python -m uvicorn src.gateway.main:app --host 0.0.0.0 --port 8080 --reload --app-dir src)
Makefile provides simple commands for running tests.
-
Run all tests:
make test-all
-
Python tests only:
make test -
Java tests only:
make test-java
-
Admin Portal tests only:
make test-admin
-
Initialize database (create
pgvectorextension): Note: not needed if usingdocker-compose.deps.yml.make migrate
-
Feed the RAG knowledge base:
-
Add your
.mdor.txtfiles todocs/. -
Run:
make ingest
-
Once the app is running (in any mode), you can send requests to the API using curl.
Note: The following assumes the authorization guard (auth_guard) in main.py is temporarily disabled for testing.
-
Test
create_tickettool:curl -X POST http://localhost:8080/v1/agents/run \ -H "Content-Type: application/json" \ -d '{"agent": "support", "input": "My internet is down, please create a ticket."}'
-
Test
get_metricstool:curl -X POST http://localhost:8080/v1/agents/run \ -H "Content-Type: application/json" \ -d '{"agent": "ops", "input": "Show me metrics for the webapp service"}'
-
Test RAG (knowledge base):
curl -X POST http://localhost:8080/v1/agents/run \ -H "Content-Type: application/json" \ -d '{"agent": "support", "input": "How can I reset my password?"}'
-
Q: I get
Connection refusedon startup.- A: Most likely the API server (
make run-local) starts before dependent containers are ready. Ensuredocker psshows(healthy)fordb,mysql, andredisbefore starting Python.
- A: Most likely the API server (
-
Q: I get
{"detail":"Missing Bearer authorization header."}.- A: That means
auth_guardinsrc/gateway/main.pyis enabled. For local
- A: That means
testing, comment out claims: dict[str, Any] = Depends(auth_guard), in the run_agent endpoint definition and pass {} as claims to orchestrator.run.
-
Q: How do I view logs for a specific service?
-
A: Use
docker logs. For example, to follow Auditor logs live:docker logs -f astradesk-auditor-1
(Container name may vary β check with
docker ps.)
-
-
Q: How do I rebuild a single Docker image?
-
A: Use the
--buildflag:docker compose up -d --build api
-
-
Q: Where can I modify
KeywordPlannerkeywords?- A: In
src/runtime/planner.py, inside the__init__method ofKeywordPlanner.
- A: In
- Run:
make test(Python),make test-java,make test-admin. - Coverage: Unit (pytest, JUnit, Vitest), integration (API flow).
- Auth: OIDC/JWT with JWKS.
- RBAC: Per tool, based on claims.
- mTLS: STRICT via Istio.
- Audit: Logged to Postgres + NATS publish.
- Policies: Allow-lists in tools, proxy retries.
- LLM integration (Bedrock/OpenAI/vLLM) with guardrails.
- Temporal for long-running workflows.
- RAG evaluations (Ragas).
- Advanced multi-tenancy & RBAC (OPA).
- Full Grafana dashboards with alerts.
- Fork the repo, create a branch, and submit a PR with tests.
- Run
make lint/typebefore committing.
Apache License 2.0. See LICENSE for details.
π Website: AstraDesk
β¨ Demo: AstraDesk Admin Portal
π§ Author: Siergej Sobolewski s.sobolewski@hotmail.com
π¬ Support channel: Support Slack
π Issues: GitHub Issues
Last updated: 2026-04-09

