Skip to content

Commit 67b9d88

Browse files
authored
Revise Geo-Auth design document with new sections
Expanded the Geo-Auth design document with detailed sections on architecture, token management, GPS validation rules, and API endpoint examples.
1 parent cd95f5e commit 67b9d88

1 file changed

Lines changed: 248 additions & 18 deletions

File tree

docs/GEO_AUTH_DESIGN.md

Lines changed: 248 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,259 @@
1-
# Geo Auth Design
1+
# Geo-Auth Design Document
22

3-
## Goals
3+
This document outlines the design for geographic authentication in the MeshCore GOME WarDriver system.
44

5-
- Provide a secure authentication mechanism for wardrive post submissions.
6-
- Prevent accidental token leakage via URLs, logs, or referrers.
7-
- Keep the client implementation simple and standards-based.
5+
## Overview
86

9-
## Confirmed Decisions
7+
The Geo-Auth system provides location-based authentication for wardriving sessions. Devices must be within designated geographic zones to connect and submit data.
108

11-
- **Token transport for wardrive posts MUST use the HTTP `Authorization: Bearer <token>` header.**
12-
- **Tokens MUST NEVER be accepted via query string parameters.**
13-
- Tokens are treated as sensitive secrets and must be stored securely on device.
14-
- If a token is compromised, it can be rotated/revoked without requiring a client app update.
9+
## Architecture
1510

16-
## Open Items
11+
### Components
1712

18-
- Ensure server and reverse-proxy logging does **not** record `Authorization` headers (or otherwise redact them), especially for wardrive endpoints.
13+
1. **Zone Manager** — Manages geographic zone definitions and capacity
14+
2. **Auth Service** — Handles authentication requests and token management
15+
3. **GPS Validator** — Validates GPS coordinates for freshness and accuracy
1916

20-
## Notes
17+
### Flow
2118

22-
### Rationale
19+
1. Device checks zone status (preflight)
20+
2. Device requests auth with coordinates
21+
3. Server validates location and issues token
22+
4. Device submits wardrive data with keepalive
23+
5. Device disconnects when session ends
2324

24-
Using the `Authorization: Bearer` header:
25+
## Zone Configuration
2526

26-
- Aligns with standard HTTP auth practices.
27-
- Avoids token exposure in shared links, browser history, referrer headers, and many default access logs.
27+
Zones are defined as circular regions with:
28+
- Center coordinates (lat/lng)
29+
- Radius in kilometers
30+
- Maximum concurrent slots
31+
- Enable/disable flag
2832

29-
Query string tokens are explicitly forbidden because they are commonly logged and leaked.
33+
## Token Management
34+
35+
Tokens are opaque bearer tokens with:
36+
- 30-minute expiration
37+
- Session binding
38+
- Zone assignment
39+
40+
## GPS Validation Rules
41+
42+
- **Staleness threshold:** 60 seconds max age
43+
- **Accuracy threshold:** 50 meters max horizontal accuracy
44+
- **Coordinate bounds:** Valid lat (-90 to 90), lng (-180 to 180)
45+
46+
---
47+
48+
## API Endpoint Examples
49+
50+
This section captures sample requests and responses for the major endpoints described in this document. See implementation notes for exact contract details.
51+
52+
> **HTTP Status Code Conventions:**
53+
> - `200 OK` — Success
54+
> - `400 Bad Request` — Missing/invalid parameters (`invalid_request`)
55+
> - `401 Unauthorized` — Missing or invalid token (`missing_token`, `bad_token`)
56+
> - `403 Forbidden` — Valid request but denied (`zone_full`, `outside_zone`, `zone_disabled`, `gps_stale`, `gps_inaccurate`)
57+
> - `429 Too Many Requests` — Rate limit exceeded (applies to `/zones/status`)
58+
59+
---
60+
61+
### Preflight — Zone Status Check
62+
63+
**Endpoint:**
64+
`POST /zones/status`
65+
Content-Type: `application/json`
66+
67+
> **Note:** POST is used (instead of GET) to allow structured JSON coordinates in the request body.
68+
69+
**Request:**
70+
```json
71+
{
72+
"lat": 45.4215,
73+
"lng": -75.6972,
74+
"accuracy_m": 15.3,
75+
"timestamp": 1703980800
76+
}
77+
```
78+
79+
**Response — In Zone (200 OK):**
80+
```json
81+
{
82+
"in_zone": true,
83+
"zone": {
84+
"name": "Ottawa",
85+
"code": "YOW",
86+
"enabled": true,
87+
"at_capacity": false,
88+
"slots_available": 5,
89+
"slots_max": 10
90+
}
91+
}
92+
```
93+
94+
**Response — Outside All Zones (200 OK):**
95+
```json
96+
{
97+
"in_zone": false,
98+
"nearest_zone": {
99+
"name": "Ottawa",
100+
"code": "YOW",
101+
"distance_km": 2.3
102+
}
103+
}
104+
```
105+
106+
**Response — GPS Too Stale (403 Forbidden):**
107+
```json
108+
{
109+
"in_zone": false,
110+
"error": true,
111+
"reason": "gps_stale"
112+
}
113+
```
114+
115+
---
116+
117+
### Auth — Connect Request
118+
119+
**Endpoint:**
120+
`POST /auth`
121+
Content-Type: `application/json`
122+
123+
**Request:**
124+
```json
125+
{
126+
"public_key": "<device_public_key>",
127+
"who": "Alice's Pixel 8",
128+
"version": "2.1.0",
129+
"reason": "connect",
130+
"coords": {
131+
"lat": 45.4216,
132+
"lng": -75.6970,
133+
"accuracy_m": 12.0,
134+
"timestamp": 1703980842
135+
}
136+
}
137+
```
138+
139+
**Response — Allowed (200 OK):**
140+
```json
141+
{
142+
"allowed": true,
143+
"token": "<opaque_bearer_token>",
144+
"session_id": "<session_id>",
145+
"zone": {
146+
"name": "Ottawa",
147+
"code": "YOW"
148+
},
149+
"expires_at": 1703982642
150+
}
151+
```
152+
153+
**Response — Denied, At Capacity (403 Forbidden):**
154+
```json
155+
{
156+
"allowed": false,
157+
"reason": "zone_full"
158+
}
159+
```
160+
161+
**Response — Denied, Outside Zone (403 Forbidden):**
162+
```json
163+
{
164+
"allowed": false,
165+
"reason": "outside_zone",
166+
"nearest_zone": {
167+
"name": "Ottawa",
168+
"code": "YOW",
169+
"distance_km": 1.2
170+
}
171+
}
172+
```
173+
174+
---
175+
176+
### Wardrive Post (Keepalive + Data Submission)
177+
178+
**Endpoint:**
179+
`POST /wardrive`
180+
Headers:
181+
- `Authorization: Bearer <token>`
182+
- `Content-Type: application/json`
183+
184+
**Request:**
185+
```json
186+
{
187+
"session_id": "<session_id>",
188+
"public_key": "<device_public_key>",
189+
"data": { ... },
190+
"coords": {
191+
"lat": 45.4217,
192+
"lng": -75.6975,
193+
"accuracy_m": 10.1,
194+
"timestamp": 1703980860
195+
}
196+
}
197+
```
198+
199+
**Response — Allowed, Session Extended (200 OK):**
200+
```json
201+
{
202+
"allowed": true,
203+
"expires_at": 1703982660
204+
}
205+
```
206+
207+
**Response — Denied, Outside Assigned Zone (403 Forbidden):**
208+
```json
209+
{
210+
"allowed": false,
211+
"reason": "outside_zone"
212+
}
213+
```
214+
215+
**Response — Denied, Invalid Token (401 Unauthorized):**
216+
```json
217+
{
218+
"allowed": false,
219+
"reason": "bad_token"
220+
}
221+
```
222+
223+
---
224+
225+
### Disconnect
226+
227+
**Endpoint:**
228+
`POST /auth`
229+
Headers:
230+
- `Authorization: Bearer <token>`
231+
- `Content-Type: application/json`
232+
233+
**Request:**
234+
```json
235+
{
236+
"reason": "disconnect",
237+
"session_id": "<session_id>"
238+
}
239+
```
240+
241+
**Response — Success (200 OK):**
242+
```json
243+
{
244+
"disconnected": true
245+
}
246+
```
247+
248+
---
249+
250+
_Add further endpoint examples as APIs expand._
251+
252+
## Open Items / Next Brainstorm
253+
254+
- [ ] Define rate limiting strategy for `/zones/status`
255+
- [ ] Decide on token refresh vs re-auth approach
256+
- [ ] Specify error response format consistency
257+
- [ ] Consider WebSocket alternative for keepalive
258+
- [ ] Document admin endpoints for zone management
259+
- [ ] Add session type? TX vs RX? RX does not require to be limited.

0 commit comments

Comments
 (0)