⚠️ SCOPE NOTICE (2026-04-16): This document describes the vision for multi-protocol support. Today, only HTTP/REST is production-ready. gRPC and GraphQL handlers exist but are stubs:GraphQLHandler.check_operation_policy/2always returns true, andGRPCHandler.forward_grpc_request/5returns a hardcoded response with no actual forwarding. Do not route gRPC or GraphQL traffic through this gateway in production.See
docs/SUPPORTED-FEATURES.mdfor the authoritative status of each protocol, andROADMAP.adocfor the MVP scope.
The HTTP Capability Gateway aims to support multiple protocols: HTTP/REST, gRPC, and GraphQL. Only HTTP/REST is currently supported end-to-end.
┌─────────────────────────────────────────────────────────────┐
│ Idris2 ABI Layer │
│ (src/abi/Protocol.idr, Types.idr) │
│ Formal interface with dependent type proofs │
└─────────────────────────────────────────────────────────────┘
▲
│
┌─────────────────────────────┼─────────────────────────────┐
│ Zig FFI Layer │ (ffi/zig/) │
│ ┌────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ gRPC │ │ GraphQL │ │ Common │ │
│ │ Parser │ │ Parser │ │ Utilities │ │
│ │ (HTTP/2) │ │ (JSON) │ │ (Endian,etc) │ │
│ └────────────┘ └──────────────┘ └────────────────┘ │
└────────────────────────────────────────────────────────────┘
▲
│
┌─────────────────────────────┼─────────────────────────────┐
│ Elixir Gateway Layer │ │
│ ┌────────────────┐ │
│ │ ProtocolRouter │ (Detects protocol) │
│ └────────┬───────┘ │
│ │ │
│ ┌─────┴─────┬──────────┬──────────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────┐ ┌──────┐ ┌────────┐ ┌──────┐ │
│ │ Gateway │ │ gRPC │ │GraphQL │ │Policy│ │
│ │(HTTP) │ │Handler│ │Handler │ │ │ │
│ └─────────┘ └──────┘ └────────┘ └──────┘ │
└────────────────────────────────────────────────────────────┘
Automatic protocol detection based on request characteristics:
- GraphQL: POST to
/graphqlendpoint - gRPC: HTTP/2 with
content-type: application/grpc* - HTTP/REST: Everything else (default)
Add to config/config.exs:
config :http_capability_gateway,
# Enable multi-protocol support
enable_grpc: true,
enable_graphql: true,
# Backend URLs
grpc_backend_url: "http://localhost:50051",
graphql_backend_url: "http://localhost:4000/graphql",
# Policy enforcement
grpc_methods_policy: "config/grpc-policy.yaml",
graphql_operations_policy: "config/graphql-policy.yaml"# config/grpc-policy.yaml
dsl_version: "1"
grpc_methods:
# Health check - public
- service: "grpc.health.v1.Health"
method: "Check"
exposure: "public"
# User service - authenticated
- service: "myapp.UserService"
method: "GetUser"
exposure: "authenticated"
# Admin service - internal only
- service: "myapp.AdminService"
method: "*" # All methods
exposure: "internal"# config/graphql-policy.yaml
dsl_version: "1"
graphql:
# Allow queries and mutations, no subscriptions
allowed_operations:
- query
- mutation
# All GraphQL requires authentication
exposure: "authenticated"
# Specific operation names can be restricted
blocked_operations:
- "AdminMutation"
- "DangerousQuery"The Zig FFI layer must be compiled before the gateway can handle gRPC/GraphQL:
cd ffi/zig
zig build
# Run tests
zig build test
# Install library
sudo cp zig-out/lib/libgateway.so /usr/local/lib/# Test gRPC endpoint
grpcurl -plaintext -d '{"service":"health"}' localhost:4000 grpc.health.v1.Health/Check
# Test GraphQL endpoint
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ user(id: 1) { name } }"}'
# Test HTTP/REST (existing)
curl http://localhost:4000/api/usersProtocol parsing performance (Zig FFI):
- gRPC: ~5μs per request
- GraphQL: ~10μs per query
- HTTP: ~2μs per request
All parsers are memory-safe with zero-copy parsing where possible.
- Type Safety: Idris2 dependent types prove correctness
- Memory Safety: Zig compile-time checks prevent buffer overflows
- Policy Enforcement: All protocols subject to verb governance
- Stealth Mode: Supported for all protocols (custom error codes)
Current implementation is in beta:
- gRPC: HTTP/2 frame parsing stub (TODO: full HPACK decoder)
- GraphQL: Basic operation detection (TODO: full AST parsing)
- Policy integration: Stubs in place (TODO: wire to PolicyCompiler)
See ffi/zig/README.md and src/abi/README.md for implementation details.