
Building "UPI for Energy" with AWS Cedar: Regulation as Code for India's Rooftop Solar
UrjaPay is a UPI-style platform enabling India's rooftop-solar homes to sell surplus electricity directly to neighbours. Sellers earn more than net-metering rates, while buyers pay less than retail tariffs. Using energy VPAs, meter-verified trades, DISCOM settlements and a tamper-evident ledger, UrjaPay enables regulated peer-to-peer energy trading. It pools colony-level clean energy into REC blocks, rewarding households with Green Points redeemable for bill discounts, EV charging and metro cards.
India is putting rooftop solar on 1 crore homes under PM Surya Ghar Muft Bijli Yojana. That's a huge amount of clean power being generated at noon on Indian rooftops. But I kept coming back to one question: where does the surplus go, and who benefits from it?
This post covers how I built UrjaPay: UPI for Energy for the AWS Bharat Builds Environmental Hacks hackathon (Waste & Energy track), and why Cedar, AWS's open-source policy language, turned out to be the core of the idea.
The problem: sold cheap, bought expensive
When a solar home exports extra units under net metering, the DISCOM typically pays around ₹3–4 per unit. The neighbour next door, a few metres away on the same transformer, pays ₹7–8+ per unit at retail.
So clean energy leaves one home cheaply and comes back into the next home expensively. And the household's green contribution is invisible: carbon markets trade in 1 MWh / 1 tonne blocks, and a single home produces only a few kWh of surplus a day.
The idea came from a visit to Samsung R&D, where people described a UPI-like infrastructure for energy: standardised rates, and individuals able to sell energy and earn, with carbon credits in the loop. I wanted to see whether that could be made practical for India today.
The idea: send electricity like you send money
UrjaPay gives every home an energy VPA, such as
sharma@urja .- Sharma-ji has rooftop solar and 6.4 kWh of meter-verified surplus.
- Gupta-ji next door has no solar.
- Sharma sells 4 kWh to Gupta at ₹5.50/unit with a UPI-style PIN.
| Today | With UrjaPay |
|---|---|---|
Seller | ₹3.50/unit feed-in | ₹5.50/unit |
Buyer | ₹8.00/unit retail | ₹6.00/unit (incl. ₹0.50 wheeling) |
DISCOM | Pays for peak power, loses power in transmission | Earns a wheeling fee, gets local balancing |
"But electricity can't physically go to the neighbour"
Correct, and it doesn't need to. Power still flows into the shared grid exactly as it does under net metering. Only the settlement is peer-to-peer: the DISCOM debits the buyer's bill, credits the seller's and keeps a wheeling fee. In UPI terms, the DISCOM plays the role NPCI plays.
Trades are allowed only between homes on the same distribution transformer, so the power genuinely stays local and the grid isn't overloaded.
Carbon, done honestly
Each solar kWh sold avoids about 0.71 kg CO₂ (CEA grid emission factor). Since households can't trade carbon credits individually, UrjaPay acts as an aggregator: it pools the colony's clean kWh into 1 MWh blocks, the size of a Renewable Energy Certificate, and returns the value as Green Points, redeemable for bill discounts, EV charging or metro cards.
The hard part: every state has different rules
This is where most "P2P energy" ideas fail a reality check. Energy is one of the most regulated sectors in India, and the rules differ from state to state: who can sell, how much per trade, at what price band, between which consumers.
If those rules are hard-coded into the app, every regulatory change needs a code change, a review and a redeploy. Regulators can't read the code, and users get an unhelpful "transaction failed".
So I made the rules data, not code, using Cedar.
How I used AWS: Cedar as "regulation as code"
Cedar is AWS's open-source authorization policy language (it also powers Amazon Verified Permissions). I used
@cedar-policy/cedar-wasm , which compiles Cedar to WebAssembly, so every trade is authorised by Cedar's isAuthorized() directly in the browser.Each home is a Cedar entity:
JSON
{"uid": { "type": "Home", "id": "sharma" },"attrs": { "netMetered": true, "kycVerified": true, "transformer": "DT-14", "surplusWh": 6400 },"parents": []}
And India's trading rules become readable policies:
cedar
// Only KYC-verified, net-metered prosumers may sell powerpermit (principal, action == Action::"sellEnergy", resource)when { principal.netMetered && principal.kycVerified };// Power stays local: buyer and seller must share a distribution transformerforbid (principal, action == Action::"sellEnergy", resource)unless { principal.transformer == resource.transformer };// Can't sell more than the smart meter has verified as surplusforbid (principal, action == Action::"sellEnergy", resource)when { context.energyWh > principal.surplusWh };// DISCOM per-trade cap, set by the regulatorforbid (principal, action == Action::"sellEnergy", resource)when { context.energyWh > 10000 };// Regulated tariff band: no price gouging during heatwavesforbid (principal, action == Action::"sellEnergy", resource)when { context.pricePaise < 400 || context.pricePaise > 700 };
Three things made Cedar a great fit:
- Forbid overrides permit. A home is permitted to sell, but any single safety rule can veto the trade. That's how regulation works in practice.
- Explainable denials.
isAuthorized()returns diagnostics with the exact policy IDs that caused a deny. UrjaPay shows them directly ("Blocked bysame-transformer: buyer is on a different distribution transformer") and highlights the policy in red.
- Live rule changes. In the demo's Regulator Console, the state regulator moves a slider (for example, lowering the per-trade cap from 10 to 2 kWh). The Cedar policies regenerate, and the very next trade obeys the new rule, with no app update and no redeploy.
A tamper-evident ledger, without crypto
Every settlement is written to a SHA-256 hash-chained ledger using the browser's Web Crypto API. Each entry stores the hash of the previous one, so editing any past trade breaks the chain from that point. The demo has a "Tamper" button to prove it.
There's no token and no cryptocurrency: money moves over UPI. The chain is just an audit trail that nobody can quietly rewrite.
Tech stack
- AWS Cedar (
@cedar-policy/cedar-wasm4.13): the policy engine for every trade
- React + Vite: the UPI-style web app
- Web Crypto (SHA-256): the hash-chained settlement ledger
- Vercel: deployed from GitHub with automatic deploys on push
- Zero backend: the whole demo runs in the browser at ₹0 cost
Challenges I ran into
- WASM loading in Vite. Cedar's default WASM loader uses
import.meta.url, which didn't resolve after Vite's dependency pre-bundling. I copiedcedar_wasm_bg.wasminto/publicand passed the path explicitly toinit({ module_or_path }).
- Integers only. Cedar's arithmetic is
Long, so I modelled energy in Wh and prices in paise (₹5.50 is550). It's a nice side effect: no floating-point rounding errors in money.
- WASM size. The Cedar WASM is about 4.3 MB (about 1.4 MB gzipped), which is noticeable on slower mobile networks in India. A server-side authorizer, or Amazon Verified Permissions, would be the production answer.
- Staying honest about regulation. The temptation was to say "households sell carbon credits". Researching it made the aggregator plus Green Points model clearly the defensible one.
Is this practical for India?
I believe so:
- P2P solar trading has been piloted in Delhi (Tata Power-DDL) and Lucknow (UPERC-approved).
- Smart meters are being rolled out at scale under RDSS, which provides the 15-minute export data UrjaPay needs.
- There is active work on an open Unified Energy Interface: a "UPI for energy".
- Rules as code means each state's regulator can have its own policy set without forking the app.
What's next
- Move the same Cedar policies to Amazon Verified Permissions, with one policy store per state regulator.
- Ingest live smart-meter data with AWS IoT Core and settle trades with AWS Lambda + API Gateway against DISCOM APIs.
- Pilot with one Delhi colony on a single transformer.
What I learned
The biggest lesson: writing policy is product design. Making India's messy, state-by-state energy rules readable, testable and explainable turned out to be more valuable than any single feature. Cedar made that possible in a few hundred lines of code.
If you're building anything in a regulated domain (energy, health, finance), try modelling the rules in Cedar before you hard-code them. Your future self, and your regulator, will thank you.
Built for AWS Bharat Builds: Environmental Hacks 2026 by WeMakeDevs × AWS Builder Center. AI tool used: Claude Code (Anthropic) for ideation, coding and documentation. Tariff figures are indicative.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article