Working-group publication repo for drone regulation and UTM standards in India.
Published site: https://ispirt.github.io/pushpaka/
pushpaka/
├── docs/ # PRIMARY OUTPUT — MkDocs knowledge base
│ ├── work-items/ # Work item specs I01–I08
│ ├── openapi/ # SOURCE-OF-TRUTH OpenAPI specs
│ │ ├── registry.yaml # UAS registry (v1.0.17)
│ │ └── flight-authorisation.yaml # Flight permits and airspace tokens
│ ├── minutes/ # Working-group meeting records
│ ├── ref/ # Reference and background documents
│ └── index.md # Microsite homepage
├── reference-implementation/ # Illustrative Java/Spring Boot services (I05 scope only)
│ ├── src/main/java/ # Registry + flight-auth service code
│ │ └── in/ispirt/pushpaka/
│ │ ├── dao/ # Hibernate entities + DaoInstance singleton
│ │ │ ├── entities/ # 16 JPA entity classes
│ │ │ └── seeds/ # Seeds.java (fixture constants) + SeedLoader.java
│ │ ├── registry/ # Registry service (controllers, services, config)
│ │ ├── flightauthorisation/ # Flight authorisation service
│ │ └── authorisation/ # SpiceDB AuthZ client
│ ├── src/test/java/
│ │ └── in/ispirt/pushpaka/
│ │ ├── unittests/ # AuthZTest (30 SpiceDB tests), AutTest (AUT generation)
│ │ └── integration/ # DemoScenario1–5 + TestUtils (HTTP end-to-end)
│ ├── src/test/resources/
│ │ └── fixtures/ # 16 JSON request-body templates ({{placeholder}} tokens)
│ ├── src/main/resources/ # Hibernate config, Spring properties, SpiceDB schema
│ ├── docker/ # Keycloak, SpiceDB, PostgreSQL service configs
│ ├── docker-compose.yaml # Full dev stack
│ ├── openapi.yaml # DOWNSTREAM COPY — generated from docs/openapi/
│ └── pom.xml # Maven build (Java 17, Spring Boot 2.7.6)
├── ardupilot/ # Submodule — pure upstream ArduPilot, no patches
├── qgroundcontrol/ # Submodule — pure upstream QGC, no patches
├── mkdocs.yml # Docs site config (theme: pulse)
├── requirements.txt # Python deps for MkDocs
├── Vagrantfile # ArduPilot dev VM (needs audit)
└── .github/workflows/
├── main.yml # Docs CI — strict build + auto-deploy to GH Pages
└── java-ci.yml # Java CI — runs tests on PRs touching reference-impl
Work items, meeting minutes, OpenAPI specs, and reference documents live under docs/ and are published as a static site via MkDocs.
pip install -r requirements.txt
mkdocs servemkdocs build --strictGitHub Actions auto-deploys to GitHub Pages on push to the dev branch. To deploy manually:
mkdocs gh-deployOpenAPI specifications are the source of truth for all API contracts.
| Spec | Location |
|---|---|
| UAS Registry | docs/openapi/registry.yaml |
| Flight Authorisation | docs/openapi/flight-authorisation.yaml |
The file reference-implementation/openapi.yaml is a downstream copy used for code generation — do not edit it directly.
To browse interactively, run the reference implementation (see below) and open:
http://localhost:8082/swagger-ui.html # Registry
http://localhost:8083/swagger-ui.html # Flight authorisation
An illustrative Java/Spring Boot implementation of the registry and flight authorisation services. Scope is intentionally limited to demonstrating the I05 UTM ConOps — it is not a production system.
| Service | Host port |
|---|---|
| PostgreSQL | 15432 |
| Keycloak | 18080 |
| SpiceDB HTTP | 18081 |
| SpiceDB gRPC | 50051 |
| Registry service | 8082 |
| Flight authorisation | 8083 |
No local Java or Maven installation needed — the devcontainer provides everything.
cp .devcontainer/.env.example .devcontainer/.env
# Edit .env if any default ports conflict with services already on your machineOpen the repo in VS Code → Reopen in Container. All services start automatically.
docker compose -f .devcontainer/docker-compose.yml upOpen this repo in Codespaces — the devcontainer starts automatically, no local setup needed.
cd /workspace/reference-implementation
mvn compile # Compile only
mvn test # All tests
mvn test -Dtest="EntityTests" # Entity tests only
mvn prettier:write # Format codeThe test suite has two tiers — unit/authZ tests that run in CI, and integration tests that require the full stack.
unittests/AuthZTest.java — 30 ordered JUnit 5 tests covering the SpiceDB authorisation layer end-to-end:
| Group | What is tested |
|---|---|
| Schema | SpiceDB schema write |
| Identities | Platform user, CAA, Manufacturer, Trader, DSSP, Repair Agency, Operator administrator creation |
| Membership | Pilot–Operator association (add, remove, negative cases) |
| Approvals | CAA approves Manufacturer, Operator, DSSP, Trader, Repair Agency |
| Lookups | UAS ownership, regulator lookup, bulk relationship export |
Tests are stateful and ordered; each builds on the prior state. Run with:
mvn test -Dtest="AuthZTest"unittests/AutTest.java — smoke test for AUT (Airspace Usage Token) generation logic. Verifies the token can be created with valid parameters.
integration/DemoScenario*.java — HTTP-level end-to-end tests against live services. Not run in CI.
| Scenario | What it exercises |
|---|---|
| DemoScenario1 | Full entity registration: CAA, Manufacturer, Operator, Pilot, DSSP, Repair Agency, Trader, UAS, UAS Sale |
| DemoScenario2 | AUT generation for BVLOS operation |
| DemoScenario3 | AUT generation for VLOS operation |
| DemoScenario4 | AUT generation for EVLOS operation |
| DemoScenario5 | Flight plan submission, conflict rejection, AUT + signing key verification, kill-switch, temporary flight restriction |
Run a specific scenario (full stack must be up):
mvn test -Dtest="DemoScenario1"Request payloads are stored as JSON templates in src/test/resources/fixtures/ — one file per entity type (e.g. manufacturer.json, uas-type.json). Placeholder tokens like {{manufacturerId}} are filled at runtime by TestUtils.fill(). This keeps test logic readable and the payloads auditable without parsing Java strings.
Keycloak is used as the identity provider. It issues JWTs that the services validate via Spring OAuth2 resource server.
| Detail | Value |
|---|---|
| Admin console | http://localhost:18080 (admin / admin) |
| Realm | pushpaka |
| Client ID | backend |
| Token endpoint | http://localhost:18080/realms/pushpaka/protocol/openid-connect/token |
The test realm is seeded from docker/keycloak-realm-pushpaka-test.json. Pre-configured test users (all with password test):
| Username | Role |
|---|---|
test.platform.admin@test.com |
Platform administrator |
test.caa.admin@test.com |
Civil Aviation Authority admin |
test.manufacturer.0.admin@test.com |
Manufacturer admin |
test.operator.0.admin@test.com |
Operator admin |
test.pilot.0@test.com |
Pilot |
test.dssp.0.admin@test.com |
DSSP admin |
test.repair.agency.0.admin@test.com |
Repair Agency admin |
test.trader.0.admin@test.com |
Trader admin |
test.uas.0.owner@test.com |
UAS owner |
To get a JWT manually (e.g. for Swagger UI or curl testing):
curl -s -X POST http://localhost:18080/realms/pushpaka/protocol/openid-connect/token \
-d "grant_type=password&client_id=backend" \
-d "username=test.caa.admin@test.com&password=test" \
| python3 -m json.tool | grep access_token# Registry (port 8082)
SPRING_PROFILES_ACTIVE=registry mvn compile exec:java \
-Dexec.mainClass="in.ispirt.pushpaka.registry.RegistryService"
# Flight authorisation (port 8083)
SPRING_PROFILES_ACTIVE=flightauthorisation mvn compile exec:java \
-Dexec.mainClass="in.ispirt.pushpaka.flightauthorisation.FlightAuthorisationService"All connection details are read from environment. See .devcontainer/.env.example for the full list. Key variables:
| Variable | Default | Used by |
|---|---|---|
DATABASE_URL |
jdbc:postgresql://localhost:15432/pushpaka?sslmode=disable |
Hibernate |
DATABASE_USER |
postgres |
Hibernate |
DATABASE_PASSWORD |
secret |
Hibernate |
KEYCLOAK_URL |
http://localhost:18080 |
Spring OAuth2 |
SPICEDB_TARGET |
localhost:50051 |
SpiceDB gRPC client |
SPICEDB_GRPC_PRESHARED_KEY |
somerandomkeyhere |
SpiceDB auth |
ArduPilot Software-in-the-Loop simulation and QGroundControl integration for end-to-end UTM flight scenario testing.
docker compose -f .devcontainer/docker-compose.yml --profile sitl up| Endpoint | Protocol | Purpose |
|---|---|---|
localhost:5760 |
TCP | MAVLink (autopilot stream) |
localhost:14550 |
UDP | QGC connection |
Download QGC from qgroundcontrol.com. Connect to localhost:14550 (UDP) — QGC auto-detects the SITL vehicle.
For Keycloak OAuth integration details see docs/integrations.md.
Issues and tasks are tracked in GitHub Issues.
Branch naming follows work item IDs (e.g. i08) or rebaseline phase IDs (e.g. rb-03-refimpl).
See CLAUDE.md for full project context and open decisions.