Skip to content

Commit 72f3faf

Browse files
committed
Deploy gds-draft docs: 6ca19a0fa67831ee82953b6442863f4355fe0377
1 parent 9b37b48 commit 72f3faf

9 files changed

Lines changed: 1288 additions & 0 deletions

gds-draft/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Green Data Space (GDS)
2+
3+
> **Note:** This documentation describes the **future state** of the GDS platform. Some features and `gds-preview` links are not yet available.
4+
5+
The Green Data Space (GDS) is a dataspace for secure, sovereign data sharing in the built environment. It enables building management platforms to access IoT sensor data — with explicit building owner approval — while keeping data owners in full control.
6+
7+
GDS is built on Poort8's NoodleBar dataspace technology and uses a Keycloak-based Participant Registry for identity management.
8+
9+
## Key capabilities
10+
11+
- **Organization onboarding** — Self-service registration with automated business register (KvK) verification
12+
- **API catalogue** — Discover and request access to data services registered by providers
13+
- **OAuth2-based access** — Standardized token-based authentication for machine-to-machine API calls
14+
- **Policy-based authorization** — Building owners approve access through Keyper; policies are enforced on every data request
15+
- **Data sovereignty** — Building owners maintain control and can revoke access at any time
16+
17+
## Participants
18+
19+
GDS involves four participant personas:
20+
21+
| Persona | Role | Primary tool |
22+
|---------|------|--------------|
23+
| **Alice** — Building Manager | Manages building operations, consumes sensor data | Self-Service Portal |
24+
| **Bob** — Building Owner | Owns or controls building data; approves or rejects access requests | Self-Service Portal / Email |
25+
| **Charlie** — IoT Sensor Platform | Registers APIs and provides building sensor data | Self-Service Portal |
26+
| **David** — Building Management Platform | Registers applications that consume building data APIs | Self-Service Portal |
27+
28+
## How it works
29+
30+
```mermaid
31+
flowchart LR
32+
subgraph Onboarding
33+
A[Organization registers] --> B[Admin verifies & approves]
34+
end
35+
subgraph Access
36+
C[David registers application] --> D[David requests API access]
37+
D --> E[Charlie approves access]
38+
end
39+
subgraph Authorization
40+
F[David requests building data via Keyper] --> G[Bob approves]
41+
G --> H[Policy registered in GDS]
42+
end
43+
subgraph Data Exchange
44+
I[David calls Charlie's API] --> J[Charlie checks policy]
45+
J --> K[Data delivered]
46+
end
47+
48+
B --> C
49+
E --> F
50+
H --> I
51+
```
52+
53+
## Two layers of access control
54+
55+
GDS uses two complementary access control mechanisms:
56+
57+
| Layer | Purpose | Managed by |
58+
|-------|---------|------------|
59+
| **API access** (Participant Registry) | Controls which applications can call which APIs | Charlie approves David's access request |
60+
| **Data authorization** (Authorization Registry) | Controls which data a consumer can access for specific buildings | Bob approves via Keyper |
61+
62+
API access grants the ability to call an API. Data authorization determines which buildings and actions are permitted within that API.
63+
64+
## Environments
65+
66+
| Environment | URL |
67+
|-------------|-----|
68+
| Self-Service Portal | [gds-preview.poort8.nl/portal ➚](https://gds-preview.poort8.nl/portal) |
69+
| GDS API documentation | [gds-preview.poort8.nl/scalar ➚](https://gds-preview.poort8.nl/scalar/) |
70+
| Keyper (approval workflow) | [keyper-preview.poort8.nl ➚](https://keyper-preview.poort8.nl/) |
71+
72+
## Choose your path
73+
74+
| I want to... | Read |
75+
|--------------|------|
76+
| Understand the technical architecture | [Architecture](architecture.md) |
77+
| Register my organization | [Organization Registration](onboarding.md) |
78+
| Use the self-service portal | [Self-Service Portal](portal-guide.md) |
79+
| Consume building data (David) | [Requesting API Access](requesting-api-access.md) then [Keyper Approval Workflow](approval-workflow.md) |
80+
| Provide building data (Charlie) | [Validating API Tokens](validating-api-tokens.md) then [Authorization Enforcement](authorization.md) |
81+
82+
## Background
83+
84+
For background on Organization Registry, Authorization Registry, and core dataspace concepts, see the [NoodleBar documentation](../noodlebar/).

gds-draft/_sidebar.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
- [← Back to Poort8 Overview](/)
2+
3+
- **Getting Started**
4+
- [Introduction](README.md)
5+
- [Architecture](architecture.md)
6+
7+
- **Participant Onboarding**
8+
- [Organization Registration](onboarding.md)
9+
- [Self-Service Portal](portal-guide.md)
10+
11+
- **For Data Service Consumers**
12+
- [Requesting API Access](requesting-api-access.md)
13+
- [Keyper Approval Workflow](approval-workflow.md)
14+
15+
- **For Data Service Providers**
16+
- [Validating API Tokens](validating-api-tokens.md)
17+
- [Authorization Enforcement](authorization.md)
18+
19+
- **Environments**
20+
- [Self-Service Portal ➚](https://gds-preview.poort8.nl/portal)
21+
22+
- **External Links**
23+
- [GDS API documentation ➚](https://gds-preview.poort8.nl/scalar/)
24+
- [Keyper API documentation ➚](https://keyper-preview.poort8.nl/scalar/?api=v1)
25+
- [NoodleBar Docs](../noodlebar/)

gds-draft/approval-workflow.md

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
# Keyper Approval Workflow
2+
3+
> **Note:** This documentation describes the **future state** of the GDS platform. Some features and `gds-preview` links are not yet available.
4+
5+
This guide is for **David** — a data service consumer who needs to request building owner approval before accessing building sensor data. It covers how to use the Keyper API to create approval requests and track their status.
6+
7+
## When to use this
8+
9+
[Requesting API Access](requesting-api-access.md) grants your application the ability to *call* a provider's API. This guide covers the next step: obtaining **data-level authorization** for specific buildings through building owner approval.
10+
11+
## Prerequisites
12+
13+
| Requirement | Description |
14+
|-------------|-------------|
15+
| API access approved | Charlie has approved your application's access to their API |
16+
| Keyper credentials | OAuth2 client credentials for Keyper (contact Poort8 at hello@poort8.nl) |
17+
| Building details known | VBO ID of the target building and building owner's organization |
18+
19+
## Overview
20+
21+
```likec4
22+
// view: approval_workflow
23+
specification {
24+
element actor
25+
element system
26+
}
27+
28+
model {
29+
alice = actor 'Building Manager (Alice)'
30+
david = actor 'Your Platform'
31+
keyper = system 'Keyper Approve'
32+
bob = actor 'Building Owner (Bob)'
33+
ar = system 'GDS Authorization Registry'
34+
}
35+
36+
views {
37+
dynamic view approval_workflow {
38+
title 'Keyper Approval Workflow'
39+
variant sequence
40+
41+
alice -> david 'Requests access to building data'
42+
david -> keyper 'POST /v1/api/approval-links'
43+
keyper -> david '201 Created (approval link ID)'
44+
keyper -> bob 'Email with approval link'
45+
bob -> keyper 'Opens link, reviews request'
46+
bob -> keyper 'Approves + enters verification code'
47+
keyper -> ar 'Registers policies'
48+
ar -> keyper 'Policies stored'
49+
david -> keyper 'GET /v1/api/approval-links/{id}'
50+
keyper -> david 'Status = Approved'
51+
}
52+
}
53+
```
54+
55+
## Step 1 — Authenticate with Keyper
56+
57+
Obtain an access token for the Keyper API:
58+
59+
```http
60+
POST https://poort8.eu.auth0.com/oauth/token
61+
Content-Type: application/json
62+
63+
{
64+
"client_id": "<YOUR_KEYPER_CLIENT_ID>",
65+
"client_secret": "<YOUR_KEYPER_CLIENT_SECRET>",
66+
"audience": "Poort8-Dataspace-Keyper-Preview",
67+
"grant_type": "client_credentials"
68+
}
69+
```
70+
71+
Response:
72+
```json
73+
{
74+
"access_token": "eyJhbGciOiJSUzI1NiIs...",
75+
"token_type": "Bearer",
76+
"expires_in": 3600
77+
}
78+
```
79+
80+
Store the token and reuse it for multiple requests until it expires (1 hour).
81+
82+
## Step 2 — Prepare required data
83+
84+
Gather the following before creating an approval request:
85+
86+
### Requester information (your platform's user)
87+
88+
| Field | Description | Example |
89+
|-------|-------------|---------|
90+
| `name` | Person initiating the request | `Alice Anderson` |
91+
| `email` | Their email address | `alice@building-opt.nl` |
92+
| `organization` | Consumer organization name | `Building Optimization Corp` |
93+
| `organizationId` | Consumer organization EUID | `NLNHR.12345678` |
94+
95+
### Approver information (building owner)
96+
97+
| Field | Description | Example |
98+
|-------|-------------|---------|
99+
| `name` | Building owner who will approve | `Bob Johnson` |
100+
| `email` | Where the approval link is sent | `bob@building-owner.nl` |
101+
| `organization` | Building owner's organization name | `Johnson Properties BV` |
102+
| `organizationId` | Building owner's organization EUID | `NLNHR.87654321` |
103+
104+
### Building and policy information
105+
106+
| Field | Description | Example |
107+
|-------|-------------|---------|
108+
| `resourceId` | VBO ID (16 digits) from the Dutch BAG registry | `0363010000659001` |
109+
| `serviceProvider` | IoT platform's organization EUID | `NLNHR.23456789` |
110+
| `action` | `GET` (read) or `POST` (write/control) | `GET` |
111+
112+
> **VBO ID lookup:** Use the [PDOK BAG API ➚](https://www.pdok.nl/introductie/-/article/basisregistratie-adressen-en-gebouwen-ba-1) to find VBO IDs by building address.
113+
114+
## Step 3 — Understand policy levels
115+
116+
| Level | Resource type | Resource ID | Actions | Description |
117+
|-------|--------------|-------------|---------|-------------|
118+
| Building | `building` | VBO ID | `GET` / `POST` | Access to entire building and all assets |
119+
| Asset | `asset` | Asset ID | `GET` / `POST` | Access to a specific sensor or control point |
120+
121+
**Action semantics:**
122+
- `GET` — Read data (sensor measurements, metadata)
123+
- `POST` — Write data or send control commands. Implicitly grants `GET` access
124+
125+
> **Pilot scope:** During the test phase, only a `GET` policy on building level (VBO ID) is used.
126+
127+
### Bundling policies
128+
129+
You can request multiple permissions in a single approval request. The building owner receives one email and makes one approval decision for all bundled policies.
130+
131+
Example: bundle `GET` and `POST` on the same building, or request access to multiple resource types.
132+
133+
## Step 4 — Create approval request
134+
135+
```http
136+
POST https://keyper-preview.poort8.nl/v1/api/approval-links
137+
Authorization: Bearer <ACCESS_TOKEN>
138+
Content-Type: application/json
139+
```
140+
141+
### Request body
142+
143+
```json
144+
{
145+
"requester": {
146+
"name": "Alice Anderson",
147+
"email": "alice@building-opt.nl",
148+
"organization": "Building Optimization Corp",
149+
"organizationId": "NLNHR.12345678"
150+
},
151+
"approver": {
152+
"name": "Bob Johnson",
153+
"email": "bob@building-owner.nl",
154+
"organization": "Johnson Properties BV",
155+
"organizationId": "NLNHR.87654321"
156+
},
157+
"dataspace": {
158+
"baseUrl": "https://gds-preview.poort8.nl"
159+
},
160+
"reference": "SENSOR-OPT-2025-Q4-001",
161+
"addPolicyTransactions": [
162+
{
163+
"useCase": "ishare",
164+
"license": "0005",
165+
"type": "building",
166+
"issuerId": "NLNHR.87654321",
167+
"subjectId": "NLNHR.12345678",
168+
"serviceProvider": "NLNHR.23456789",
169+
"action": "GET",
170+
"resourceId": "0363010000659001",
171+
"attribute": "*",
172+
"notBefore": 1730736000,
173+
"expiration": 2147483647
174+
}
175+
],
176+
"orchestration": {
177+
"flow": "gds.klimaatsensoren@v1"
178+
}
179+
}
180+
```
181+
182+
### Key fields
183+
184+
| Field | Description |
185+
|-------|-------------|
186+
| `dataspace.baseUrl` | GDS Authorization Registry URL |
187+
| `reference` | Your internal tracking reference |
188+
| `addPolicyTransactions` | Array of policies to register upon approval |
189+
| `orchestration.flow` | Approval workflow identifier (`gds.klimaatsensoren@v1`) |
190+
| `notBefore` | Policy start time (Unix timestamp) |
191+
| `expiration` | Policy end time (`2147483647` for no expiration) |
192+
193+
## Step 5 — Handle the response
194+
195+
### Success (201 Created)
196+
197+
```json
198+
{
199+
"id": "474e19af-8165-4b85-ad03-be81f9f8dcc2",
200+
"reference": "SENSOR-OPT-2025-Q4-001",
201+
"url": "https://keyper-preview.poort8.nl/approve/474e19af-8165-4b85-ad03-be81f9f8dcc2",
202+
"expiresAtUtc": 1730739600,
203+
"status": "Active"
204+
}
205+
```
206+
207+
| Field | Description |
208+
|-------|-------------|
209+
| `id` | Unique approval link ID |
210+
| `reference` | Your tracking reference (echoed) |
211+
| `url` | Approval link sent to building owner |
212+
| `expiresAtUtc` | When the link expires (Unix timestamp) |
213+
| `status` | Current status |
214+
215+
**What happens next:**
216+
1. Keyper emails Bob with the approval link
217+
2. Bob opens the link and reviews the request
218+
3. Bob approves or rejects
219+
4. If approved, Bob enters an email verification code
220+
5. Keyper registers policies in the GDS Authorization Registry
221+
222+
### Error responses
223+
224+
| Code | Cause | Action |
225+
|------|-------|--------|
226+
| `400 Bad Request` | Missing or invalid fields | Check `errors` object, correct fields, retry |
227+
| `401 Unauthorized` | Missing or expired token | Request a new token, retry |
228+
| `500 Internal Server Error` | Server-side error | Retry after short delay; contact Poort8 if persistent |
229+
230+
## Step 6 — Check approval status
231+
232+
Poll the approval link status:
233+
234+
```http
235+
GET https://keyper-preview.poort8.nl/v1/api/approval-links/{APPROVAL_LINK_ID}
236+
Authorization: Bearer <ACCESS_TOKEN>
237+
```
238+
239+
Response:
240+
```json
241+
{
242+
"id": "474e19af-8165-4b85-ad03-be81f9f8dcc2",
243+
"reference": "SENSOR-OPT-2025-Q4-001",
244+
"status": "Approved"
245+
}
246+
```
247+
248+
> **Note:** The GET response returns the full approval link entity. The `status` field is the most relevant for polling purposes.
249+
250+
**Status values:**
251+
252+
| Status | Meaning |
253+
|--------|---------|
254+
| `Active` | Awaiting building owner's decision |
255+
| `Approved` | Approved — policies are registered |
256+
| `Rejected` | Building owner rejected the request |
257+
| `Expired` | Link expired before a decision was made |
258+
259+
**Polling strategy:** Check every 5–10 minutes while status is `Active`. Stop when status changes.
260+
261+
## After approval
262+
263+
Once status is `Approved`:
264+
1. Policies are registered in the GDS Authorization Registry
265+
2. Your platform can request building data from Charlie's API
266+
3. Charlie will verify the policy via [Authorization Enforcement](authorization.md) and deliver data
267+
268+
## Support
269+
270+
For questions or issues with the Keyper approval workflow:
271+
272+
- **Contact:** hello@poort8.nl
273+
- **API reference:** [Keyper API documentation ➚](https://keyper-preview.poort8.nl/scalar/?api=v1)

0 commit comments

Comments
 (0)