A production-ready, plugin-based middleware adapter for the Beckn Protocol
Overview • Features • Architecture • Key Aspects • Quick Start • Documentation • Contributing
In August 2025, a completely new Beckn-ONIX adapter was made available. This version introduces a Plugin framework at it's core. The ONIX Adapter previous to this release is archived to a separate branch, main-pre-plugins for reference.
Beckn-ONIX is an enterprise-grade middleware adapter system designed to facilitate seamless communication in any Beckn-enabled network. It acts as a protocol adapter between Beckn Application Platforms (BAPs - buyer applications) and Beckn Provider Platforms (BPPs - seller platforms), ensuring secure, validated, and compliant message exchange across various commerce networks.
The Beckn Protocol is an open protocol that enables location-aware, local commerce across any platform and any domain. It allows creation of open, decentralized networks where:
- Platform Independence: Buyers and sellers can transact regardless of the platforms they use
- Interoperability: Seamless communication between different systems using standardized protocols
- Domain Agnostic: Works across retail, mobility, healthcare, logistics, and other domains
- Network Neutral: Can be deployed in any Beckn-compliant network globally
- BAP (Beckn Application Platform): Buyer-side applications that help users search for and purchase products/services (e.g., consumer apps, aggregators)
- BPP (Beckn Provider Platform): Seller-side platforms that provide products/services (e.g., merchant platforms, service providers)
- Beckn Network: Any network implementing the Beckn Protocol for enabling open commerce
- Dynamic Plugin Loading: Load and configure plugins at runtime without code changes
- Extensible Design: Easy to add new functionality through custom plugins
- Hot-Swappable Components: Update plugins without application restart (in development)
- Ed25519 Digital Signatures: Cryptographically secure message signing and validation
- HashiCorp Vault Integration: Centralized secrets and key management
- Request Authentication: Every message is authenticated and validated
- TLS/SSL Support: Encrypted communication channels
- JSON Schema Validation: Ensures all messages comply with Beckn protocol specifications
- Version Management: Support for multiple protocol versions simultaneously
- Domain-Specific Schemas: Tailored validation for different business domains
- Redis Caching: Response caching for improved performance
- RabbitMQ Integration: Asynchronous message processing via message queues
- Connection Pooling: Efficient resource utilization
- Configurable Timeouts: Fine-tuned performance controls
- Structured Logging: JSON-formatted logs with contextual information
- Transaction Tracking: End-to-end request tracing with unique IDs
- OpenTelemetry Metrics: Performance and business metrics collection
- Runtime Instrumentation: Go runtime + Redis client metrics included
- Health Checks: Liveness and readiness probes for Kubernetes
- Retail & E-commerce: Product search, order management, fulfillment tracking
- Mobility Services: Ride-hailing, public transport, vehicle rentals
- Logistics: Shipping, last-mile delivery, returns management
- Healthcare: Appointments, telemedicine, pharmacy services
- Financial Services: Loans, insurance, payments
┌─────────────────────────────────────────────────────────┐
│ HTTP Request │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ Module Handler │
│ (bapTxnReceiver/Caller or bppTxnReceiver/Caller) │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ Processing Pipeline │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Middleware │→ │ Steps │→ │ Plugins │ │
│ │(preprocess) │ │(validate, │ │(cache,router│ │
│ └─────────────┘ │route, sign) │ │validator...)│ │
│ └─────────────┘ └─────────────┘ │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ External Services/Response │
└─────────────────────────────────────────────────────────┘
bapTxnReceiver: Receives callback responses at BAPbapTxnCaller: Sends requests from BAP to BPPbppTxnReceiver: Receives requests at BPPbppTxnCaller: Sends responses from BPP to BAP
validateSign: Validates digital signatures on incoming requestsaddRoute: Determines routing based on configurationvalidateSchema: Validates against JSON schemassign: Signs outgoing requestscache: Caches requests/responsespublish: Publishes messages to queue
- Cache: Redis-based response caching
- Router: YAML-based routing rules engine for request forwarding (supports domain-agnostic routing for Beckn v2.x.x)
- Registry: Standard Beckn registry or Beckn One DeDi registry lookup for participant information
- Signer: Ed25519 digital signature creation for outgoing requests
- SignValidator: Ed25519 signature validation for incoming requests
- SchemaValidator: JSON schema validation
- Schemav2Validator: OpenAPI 3.x schema validation with action-based matching
- KeyManager: HashiCorp Vault integration for production key management
- SimpleKeyManager: Embedded key management for local development (no external dependencies)
- Publisher: RabbitMQ message publishing for asynchronous processing
- Encrypter: AES encryption for sensitive data protection
- Decrypter: AES decryption for encrypted data processing
- ReqPreprocessor: Request preprocessing (UUID generation, headers)
- ReqMapper: Step plugin (id:
reqmapper) used by the handler'stransformPayloadstep to transform payloads at an explicit point in the pipeline. - OtelSetup: Observability setup for metrics, traces, and logs (OTLP). Supports optional audit log configuration via
auditFieldsConfig(YAML mapping actions to fields) . See CONFIG.md for details. - OpaPolicyChecker: OPA-based network business policy enforcement. Evaluates Rego policies per request; supports network-specific policy configs, signed policy artifact verification, manifest-backed policies, and hot-reload. See plugin docs.
- ManifestLoader: Fetches a network manifest published by a Network Facilitator Organization (NFO), verifies its detached signature, and caches the verified document for downstream consumers such as
opapolicychecker. See plugin docs. - PayloadStore: Records every inbound request payload indexed by
message_idandtransaction_idwith TTL-based expiration via the cache backend. Enables stateful use cases (duplicate detection, transaction history) without requiring other plugins to manage storage. See plugin docs. - SchemaVersionMediator: Allows network participants to evolve their domain schemas independently — without coordinating changes with the rest of the network. When a BAP and BPP declare different schema object versions in their node manifests, the mediator fetches JSONata translation artifacts from the network's artifact registry and patches the payload in-flight so each side receives data in the version it expects. This enables Beckn networks to evolve organically: a participant can adopt a new schema version the moment their own node is ready, without blocking or breaking their counterparties. See plugin docs.
- VCValidator: Step plugin (id:
validateVC) that verifies W3C Verifiable Credentials embedded in request payloads for configured beckn actions — proof signature (did:key / did:jwk / did:web), issuer binding, validity window, and revocation (StatusList2021/Bitstring, DEDI) — rejecting failures with a signed NACK before routing. See plugin docs.
Beckn-ONIX emits structured logs, OpenTelemetry metrics, and distributed traces via the otelsetup plugin. A reference collector stack (OpenTelemetry Collector, Grafana, Loki) is included in install/network-observability/ for local and production use.
See OBSERVABILITY.md for the full architecture, signal catalogue, and setup guide.
The opapolicychecker plugin evaluates OPA Rego policies against every Beckn request. Policies can be scoped per network, distributed as signed artifacts by a Network Facilitator Organization (NFO), and hot-reloaded without a restart.
See opapolicychecker README for policy authoring, configuration, signature verification, and manifest-backed policy setup.
Beckn-ONIX is benchmarked end-to-end using Go's native testing.B framework — no Docker or external services required.
# Install benchstat (one-time)
go install golang.org/x/perf/cmd/benchstat@latest
# Run all benchmark scenarios and generate report
bash benchmarks/run_benchmarks.shResults land in benchmarks/results/<timestamp>/. The latest committed report is at benchmarks/results/BENCHMARK_REPORT.md. See benchmarks/README.md for full methodology and interpretation guidance.
- Go 1.26.8 or higher — the version
go.modrequires, and the floor that clears the current Go standard-library advisories (make security) - Redis (for caching)
- Docker (optional, for containerized deployment)
- Clone the repository
git clone https://github.com/OpenAgriNet/network-adapter.git
cd network-adapter- Build the application
go build -o server cmd/adapter/main.go- Build plugins
./install/build-plugins.sh- Extract schemas
unzip schemas.zip- Start Redis (if not running)
docker run -d -p 6379:6379 redis:alpine- Update the config file
Note: You can modify the configuration file to suit your environment before starting the server. ONIX adapter/server must be restarted to reflect any change made to the config file.
The following config change is required to all cache related entries in order to connect to redis that was started earlier.
cache:
id: cache
config:
addr: localhost:6379- Run the application
./server --config=config/local-simple.yamlThe server will start on http://localhost:8081
For local setup, starts only redis and onix adapter:
# Clone and setup everything automatically
git clone https://github.com/OpenAgriNet/network-adapter.git
cd network-adapter/install
chmod +x setup.sh
./setup.shThis automated script will:
- Start Redis container
- Build all plugins with correct Go version
- Build the adapter server
- Start ONIX adapter in Docker
- Create environment configuration
Note:
- Schema Validation: Extract schemas before running:
unzip schemas.zip(required forschemavalidatorplugin) - Alternative: You can use
schemav2validatorplugin instead, which fetches schemas from a URL and doesn't require local schema extraction. See CONFIG.md for more configuration details. - Optional: Before running the automated setup, build the adapter image and update
docker-compose-adapter.yamlto use the correct image
# from the repository root
docker build -f Dockerfile.adapter-with-plugins -t beckn-onix:latest .For detailed setup instructions, see SETUP.md
Services Started:
- Redis: localhost:6379
- ONIX Adapter: http://localhost:8081
Note: Start redis before before running onix adapter.
# Build the Docker image
docker build -t beckn-onix:latest -f Dockerfile.adapter-with-plugins .
# Run the container
docker run -p 8081:8081 \
-v $(pwd)/config:/app/config \
-v $(pwd)/schemas:/app/schemas \
-e CONFIG_FILE="/app/config/local-simple.yaml" \
beckn-onix:latestcurl -X POST http://localhost:8081/bap/caller/search \
-H "Content-Type: application/json" \
-d '{
"context": {
"domain": "nic2004:60221",
"country": "IND",
"city": "std:080",
"action": "search",
"version": "0.9.4",
"bap_id": "bap.example.com",
"bap_uri": "https://bap.example.com/beckn",
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"timestamp": "2023-06-15T09:30:00.000Z",
"ttl": "PT30S"
},
"message": {
"intent": {
"fulfillment": {
"start": {
"location": {
"gps": "12.9715987,77.5945627"
}
},
"end": {
"location": {
"gps": "12.9715987,77.5945627"
}
}
}
}
}
}'appName: "beckn-onix"
log:
level: debug
destinations:
- type: stdout
http:
port: 8080
timeout:
read: 30
write: 30
idle: 30
pluginManager:
root: ./plugins
modules:
- name: bapTxnReceiver
path: /bap/receiver/
handler:
type: std
role: bap
plugins:
cache:
id: cache
config:
addr: localhost:6379
router:
id: router
config:
routingConfig: ./config/routing.yaml
schemaValidator:
id: schemavalidator # or schemav2validator
config:
schemaDir: ./schemas # for schemavalidator
# type: url # for schemav2validator
# location: https://example.com/spec.yaml
steps:
- validateSign
- addRoute
- validateSchema- Combined Mode: Single instance handling both BAP and BPP (
config/onix/) - Usessecretskeymanager(HashiCorp Vault) for production key management - BAP-Only Mode: Dedicated buyer-side deployment (
config/onix-bap/) - BPP-Only Mode: Dedicated seller-side deployment (
config/onix-bpp/) - Local Development Combined Mode: Simplified configuration (
config/local-simple.yaml) - Usessimplekeymanagerwith embedded Ed25519 keys, no vault setup needed - Local Development Combined Mode (Alternative): Development configuration (
config/local-dev.yaml) - Useskeymanager, vault setup needed - Local with Observability (BAP/BPP): Configs
config/local-beckn-one-bap.yamlandconfig/local-beckn-one-bpp.yamlinclude OtelSetup (metrics, traces, audit logs) for use with an OTLP collector. Audit fields are configured viaconfig/audit-fields.yaml. For a full stack (collectors, Grafana, Loki), seeinstall/network-observability/
| Method | Endpoint | Description |
|---|---|---|
| POST | /bap/caller/search |
Search for products/services |
| POST | /bap/caller/select |
Select specific items |
| POST | /bap/caller/init |
Initialize order |
| POST | /bap/caller/confirm |
Confirm order |
| POST | /bap/caller/status |
Check order status |
| POST | /bap/caller/track |
Track order/shipment |
| POST | /bap/caller/cancel |
Cancel order |
| POST | /bap/caller/update |
Update order |
| POST | /bap/caller/rating |
Submit rating |
| POST | /bap/caller/support |
Get support |
| Method | Endpoint | Description |
|---|---|---|
| POST | /bpp/receiver/* |
Receives all BAP requests |
| POST | /bpp/caller/on_* |
Sends responses back to BAP |
- Setup Guide: Complete installation, configuration, and deployment instructions
- Configuration Guide: Description of Configuration concepts and all config parameters
- Contributing: Guidelines for contributors
- Governance: Project governance model
- License: Apache 2.0 license details
The project includes a Next.js-based GUI component located in onix-gui/ that provides:
- Visual configuration management
- Request/response monitoring
- Plugin status dashboard
- Routing rules editor
Use the make targets rather than a bare go test ./.... The plugin packages
have to be carved out of the race-instrumented build: pkg/plugin and
benchmarks/e2e compile a real .so with go build -buildmode=plugin and
then plugin.Open it in the same run, and a race-instrumented test binary
cannot load a non-race .so. make test splits the invocation accordingly;
go test -race ./... does not, and fails in a way that looks like a bug in the
plugin loader.
make test # both suites, race detection where it is safe
make cover # the same, writing a merged profile to coverage.out
make cover-diff # coverage of the files this branch changed vs BASE_REF
make lint # golangci-lint run + fmt --diff
make build # the adapter binary, into bin/
# A single package is still a plain go test
go test ./pkg/plugin/implementation/cache -vmake cover-diff is the coverage gate, and it is scoped to the diff on
purpose: the repo's whole-tree total is below MIN_COVERAGE, so a whole-repo
gate would fail every PR over a backlog none of them created. What a review can
act on is the number for the lines the PR itself touched.
Three scanners, because they are blind to different things:
make trivy-deps # the module graph — catches a vulnerable module only the
# tests import, which never reaches a layer
make docker && make trivy-image
# the image — base layers plus the Go build info compiled
# into the binary, so a toolchain CVE shows up here
make trivy-gate # fails if either SARIF report carries a finding
make security # govulncheck: the call graph, so it reports a CVE only
# when the vulnerable symbol is actually reachablemake security is also the only one that judges the toolchain go.mod
requires rather than the one the Dockerfile pins — which is why the
prerequisite above names a specific patch version.
| Workflow | Runs on | What it answers |
|---|---|---|
ci.yml |
every PR, and pushes to the trunk | Does this diff build, test and scan clean? Posts the coverage and Trivy comments. |
codeql.yml |
every PR, trunk, weekly | Does the code in this repo contain a vulnerability — injection, request forgery, key material reaching a log? Reports to the Security tab; does not block. |
coverage.yml |
trunk only | What is the whole-repo total, for the badge. |
security.yml |
trunk, weekly | Is anything wrong with the trunk today — including a CVE published against code nobody has touched since? |
ci-release.yml |
version tags | Build, rescan and publish the images a release ships. |
The weekly schedules are the point of the last two: a PR scan can only tell you whether a diff introduced something, and almost every real finding arrives against code that has not changed.
Every CI step is a one-line make call, so a red check reproduces locally by
running the command its log shows. Thresholds and tool versions live in the
Makefile, never duplicated into a workflow env: block.
The two badges at the top read release-0.0.1 — the branch this service
actually ships from — and they are measured after a merge, not on a pull
request. The per-PR gates are the first two rows above.
We welcome contributions! Please see our Contributing Guide for details on:
- Code of Conduct
- Development process
- Submitting pull requests
- Reporting issues
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security advisories: Code scanning alerts — see also SECURITY.md
Upstream — the protocol adapter this fork tracks — is beckn/beckn-onix; issues about the Beckn adapter itself, rather than about this OpenAgriNet deployment of it, belong there.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Beckn Foundation for the protocol specifications
| Contributor | Organization | Github ID |
|---|---|---|
| Ashish Guliya | Google Cloud | ashishkgGoogle |
| Pooja Joshi | Google Cloud | poojajoshi2 |
| Deepa Mulchandani | Google Cloud | Deepa-Mulchandani |
| Ankit | Beckn Labs | ankitShogun |
| Abhishek | Beckn Labs | em-abee |
| Viraj Kulkarni | Beckn Labs | viraj89 |
| Amay Pandey | Google Cloud | |
| Dipika Prasad | Google Cloud | DipikaPrasad |
| Tanya Madaan | ONDC | tanyamadaan |
| Binu | ONDC | |
| Faiz M | Beckn Labs | faizmagic |
| Ravi Prakash | Beckn Labs | ravi-prakash-v |
| Siddharth Prakash | Google Cloud | |
| Namya Patiyal | Google Cloud | |
| Saksham Nagpal | Google Cloud | sakshamGoogle |
| Arpit Bharadwaj | Google Cloud | |
| Pranoy | Google Cloud | |
| Mayuresh Nirhali | Beckn Labs | nirmay |
| Madhuvandhini B | Google Cloud | madhuvandhini5856 |
| Siddhartha Banerjee | Google Cloud | sidb85 |
| Manendra Pal Singh | NPCI BHIM | manendrapalsingh |