soajs.controller 4.2.41 → 4.2.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +43 -0
- package/.github/workflows/release.yml +92 -0
- package/ARCHITECTURE.md +193 -0
- package/Gruntfile.js +1 -1
- package/docs/configuration-custom-registry.md +421 -0
- package/docs/configuration-services-config.md +275 -0
- package/docs/data-flow.md +138 -0
- package/docs/deployment.md +205 -0
- package/docs/external-integrations.md +159 -0
- package/docs/gateway-routes.md +259 -0
- package/docs/maintenance-routes.md +308 -0
- package/docs/middleware/awareness.md +120 -0
- package/docs/middleware/cors.md +88 -0
- package/docs/middleware/enhancer.md +75 -0
- package/docs/middleware/favicon.md +36 -0
- package/docs/middleware/gotoService.md +146 -0
- package/docs/middleware/ip2ban.md +70 -0
- package/docs/middleware/key.md +196 -0
- package/docs/middleware/keyACL.md +139 -0
- package/docs/middleware/lastSeen.md +111 -0
- package/docs/middleware/maintenanceMode.md +81 -0
- package/docs/middleware/mt.md +188 -0
- package/docs/middleware/oauth.md +173 -0
- package/docs/middleware/response.md +106 -0
- package/docs/middleware/soajs.md +71 -0
- package/docs/middleware/traffic.md +190 -0
- package/docs/middleware/url.md +102 -0
- package/docs/multi-tenant-security.md +183 -0
- package/docs/request-flow.md +230 -0
- package/docs/service-discovery.md +167 -0
- package/mw/gotoService/redirectToService.js +15 -4
- package/mw/key/index.js +16 -1
- package/mw/lastSeen/index.js +3 -0
- package/mw/mt/urac.js +21 -1
- package/mw/mt/utils.js +2 -0
- package/package.json +7 -7
- package/test/integration/UC1-gateway-routes/index.js +2 -2
- package/test/unit/mw/key/index.js +150 -0
- package/test/unit/mw/lastSeen/index.js +5 -4
- package/test/unit/mw/mt/urac.js +157 -4
- package/test/unit/mw/mt/utils.js +6 -6
- package/.travis.yml +0 -72
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Response Middleware
|
|
2
|
+
|
|
3
|
+
**File:** `mw/response/index.js`
|
|
4
|
+
|
|
5
|
+
**Order:** 4
|
|
6
|
+
|
|
7
|
+
The Response middleware adds standardized response builder methods to the request object.
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
- Adds `req.soajs.buildResponse()` for creating SOAJS-formatted responses
|
|
12
|
+
- Adds `req.soajs.controllerResponse()` for sending gateway responses
|
|
13
|
+
- Provides consistent error/success response structure
|
|
14
|
+
|
|
15
|
+
## Flow
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
Incoming Request
|
|
19
|
+
│
|
|
20
|
+
▼
|
|
21
|
+
┌─────────────────────────┐
|
|
22
|
+
│ Attach buildResponse() │ Creates SOAJS response objects
|
|
23
|
+
└────────────┬────────────┘
|
|
24
|
+
│
|
|
25
|
+
▼
|
|
26
|
+
┌─────────────────────────────┐
|
|
27
|
+
│ Attach controllerResponse()│ Sends JSON responses
|
|
28
|
+
└────────────┬────────────────┘
|
|
29
|
+
│
|
|
30
|
+
▼
|
|
31
|
+
next()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Methods Added
|
|
35
|
+
|
|
36
|
+
### `req.soajs.buildResponse(error, data)`
|
|
37
|
+
|
|
38
|
+
Creates a SOAJS-formatted response object.
|
|
39
|
+
|
|
40
|
+
**Parameters:**
|
|
41
|
+
- `error` - Error object or array of errors (optional)
|
|
42
|
+
- `data` - Response data (optional)
|
|
43
|
+
|
|
44
|
+
**Returns:**
|
|
45
|
+
```javascript
|
|
46
|
+
// Success
|
|
47
|
+
{
|
|
48
|
+
"result": true,
|
|
49
|
+
"data": { ... }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Error
|
|
53
|
+
{
|
|
54
|
+
"result": false,
|
|
55
|
+
"errors": {
|
|
56
|
+
"codes": [100, 101],
|
|
57
|
+
"details": [
|
|
58
|
+
{ "code": 100, "message": "Error message" },
|
|
59
|
+
{ "code": 101, "message": "Another error" }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `req.soajs.controllerResponse(jsonObj)`
|
|
66
|
+
|
|
67
|
+
Sends a JSON response and ends the request.
|
|
68
|
+
|
|
69
|
+
**Parameters:**
|
|
70
|
+
- `jsonObj` - Response object with optional `status`, `headObj`, `code`, `msg`
|
|
71
|
+
|
|
72
|
+
**Examples:**
|
|
73
|
+
```javascript
|
|
74
|
+
// Success response
|
|
75
|
+
req.soajs.controllerResponse({ data: { user: "john" } });
|
|
76
|
+
|
|
77
|
+
// Error response
|
|
78
|
+
req.soajs.controllerResponse({
|
|
79
|
+
status: 403,
|
|
80
|
+
code: 150,
|
|
81
|
+
msg: "Access denied"
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// With custom headers
|
|
85
|
+
req.soajs.controllerResponse({
|
|
86
|
+
status: 429,
|
|
87
|
+
msg: "Too many requests",
|
|
88
|
+
headObj: {
|
|
89
|
+
"Retry-After": 60,
|
|
90
|
+
"X-RateLimit-Limit": 100
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Response Format
|
|
96
|
+
|
|
97
|
+
All responses include:
|
|
98
|
+
- `Content-Type: application/json` header
|
|
99
|
+
- HTTP status code (default: 200)
|
|
100
|
+
- JSON body
|
|
101
|
+
|
|
102
|
+
## Usage Notes
|
|
103
|
+
|
|
104
|
+
- `controllerResponse()` only available when `controllerResponse: true` in config
|
|
105
|
+
- Prevents double-ending responses (tracks `ended` state)
|
|
106
|
+
- Automatically formats errors using `buildResponse()` when `code` and `msg` provided
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# SOAJS Middleware
|
|
2
|
+
|
|
3
|
+
**File:** `mw/soajs/index.js`
|
|
4
|
+
|
|
5
|
+
**Order:** 1
|
|
6
|
+
|
|
7
|
+
The SOAJS middleware is the first middleware in the pipeline. It initializes the `req.soajs` context object that all subsequent middleware depend on.
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
- Creates the `req.soajs` namespace
|
|
12
|
+
- Attaches the logger instance
|
|
13
|
+
- Attaches the current registry reference
|
|
14
|
+
- Attaches core utility modules (meta, validator)
|
|
15
|
+
|
|
16
|
+
## Flow
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Incoming Request
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
┌─────────────────┐
|
|
23
|
+
│ Create │ if (!req.soajs) req.soajs = {}
|
|
24
|
+
│ req.soajs │
|
|
25
|
+
└────────┬────────┘
|
|
26
|
+
│
|
|
27
|
+
▼
|
|
28
|
+
┌─────────────────┐
|
|
29
|
+
│ Attach Logger │ req.soajs.log = log
|
|
30
|
+
└────────┬────────┘
|
|
31
|
+
│
|
|
32
|
+
▼
|
|
33
|
+
┌─────────────────┐
|
|
34
|
+
│ Attach │ req.soajs.registry = registryModule.get()
|
|
35
|
+
│ Registry │
|
|
36
|
+
└────────┬────────┘
|
|
37
|
+
│
|
|
38
|
+
▼
|
|
39
|
+
┌─────────────────┐
|
|
40
|
+
│ Attach Core │ req.soajs.meta = core.meta
|
|
41
|
+
│ Modules │ req.soajs.validator = core.validator
|
|
42
|
+
└────────┬────────┘
|
|
43
|
+
│
|
|
44
|
+
▼
|
|
45
|
+
next()
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
{
|
|
52
|
+
"log": logger, // Logger instance
|
|
53
|
+
"core": coreModule // soajs.core.libs module
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Properties Set
|
|
58
|
+
|
|
59
|
+
| Property | Type | Description |
|
|
60
|
+
|----------|------|-------------|
|
|
61
|
+
| `req.soajs.log` | object | Logger instance for request-scoped logging |
|
|
62
|
+
| `req.soajs.registry` | object | Current environment registry |
|
|
63
|
+
| `req.soajs.meta` | object | Metadata utilities from core |
|
|
64
|
+
| `req.soajs.validator` | object | JSON schema validator |
|
|
65
|
+
|
|
66
|
+
## Usage Notes
|
|
67
|
+
|
|
68
|
+
- This middleware MUST be first in the pipeline
|
|
69
|
+
- All other middleware assume `req.soajs` exists
|
|
70
|
+
- The registry is fetched fresh on each request (reference, not copy)
|
|
71
|
+
- Logger supports: `debug()`, `info()`, `warn()`, `error()`, `fatal()`
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Traffic Middleware
|
|
2
|
+
|
|
3
|
+
**File:** `mw/traffic/index.js`
|
|
4
|
+
|
|
5
|
+
**Order:** 16
|
|
6
|
+
|
|
7
|
+
The Traffic middleware implements rate limiting (throttling) with configurable strategies and storage backends.
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
- Enforces rate limiting per tenant/IP
|
|
12
|
+
- Supports configurable throttling strategies
|
|
13
|
+
- Provides memory and MongoDB storage backends
|
|
14
|
+
- Returns rate limit headers in responses
|
|
15
|
+
|
|
16
|
+
## Flow
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Incoming Request
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
┌─────────────────────────┐
|
|
23
|
+
│ Check Prerequisites │ registry, tenant, controller exist?
|
|
24
|
+
└────────┬────────────────┘
|
|
25
|
+
│
|
|
26
|
+
├─── Missing ──▶ next()
|
|
27
|
+
│
|
|
28
|
+
▼
|
|
29
|
+
┌─────────────────────────┐
|
|
30
|
+
│ Determine Strategy │ publicAPIStrategy or privateAPIStrategy
|
|
31
|
+
└────────┬────────────────┘
|
|
32
|
+
│
|
|
33
|
+
├─── No strategy ──▶ next()
|
|
34
|
+
│
|
|
35
|
+
▼
|
|
36
|
+
┌─────────────────────────┐
|
|
37
|
+
│ Get Throttling Config │ Priority:
|
|
38
|
+
│ │ 1. servicesConfig.gateway.throttling
|
|
39
|
+
│ │ 2. custom.gateway.value.traffic.throttling
|
|
40
|
+
│ │ 3. serviceConfig.throttling
|
|
41
|
+
└────────┬────────────────┘
|
|
42
|
+
│
|
|
43
|
+
▼
|
|
44
|
+
┌─────────────────────────┐
|
|
45
|
+
│ Check Throttling │ Get/increment counter
|
|
46
|
+
│ Counter │ Compare to limit
|
|
47
|
+
└────────┬────────────────┘
|
|
48
|
+
│
|
|
49
|
+
├─── Under limit ──▶ next()
|
|
50
|
+
│
|
|
51
|
+
├─── Over limit, retries left ──▶ Delay and retry
|
|
52
|
+
│
|
|
53
|
+
└─── Over limit, no retries ──▶ 429 Too Many Requests
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Configuration
|
|
57
|
+
|
|
58
|
+
### Strategy Definition
|
|
59
|
+
|
|
60
|
+
Located in `registry.serviceConfig.throttling`:
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
{
|
|
64
|
+
"throttling": {
|
|
65
|
+
"publicAPIStrategy": "default", // For unauthenticated requests
|
|
66
|
+
"privateAPIStrategy": "heavy", // For authenticated requests
|
|
67
|
+
"default": {
|
|
68
|
+
"status": 1, // 0=Off, 1=On
|
|
69
|
+
"type": 1, // 0=tenant, 1=tenant+IP
|
|
70
|
+
"window": 60000, // Time window in ms
|
|
71
|
+
"limit": 50, // Max requests per window
|
|
72
|
+
"retries": 2, // Retries when over limit
|
|
73
|
+
"delay": 1000 // Delay between retries (ms)
|
|
74
|
+
},
|
|
75
|
+
"heavy": {
|
|
76
|
+
"status": 1,
|
|
77
|
+
"type": 1,
|
|
78
|
+
"window": 60000,
|
|
79
|
+
"limit": 500,
|
|
80
|
+
"retries": 2,
|
|
81
|
+
"delay": 1000
|
|
82
|
+
},
|
|
83
|
+
"strict": {
|
|
84
|
+
"status": 1,
|
|
85
|
+
"type": 1,
|
|
86
|
+
"window": 60000,
|
|
87
|
+
"limit": 10,
|
|
88
|
+
"retries": 0,
|
|
89
|
+
"delay": 0
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Service-Specific Override
|
|
96
|
+
|
|
97
|
+
Via custom registry or tenant config:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
{
|
|
101
|
+
"throttling": {
|
|
102
|
+
"oauth": {
|
|
103
|
+
"publicAPIStrategy": "strict",
|
|
104
|
+
"apis": ["/token"] // Only these APIs
|
|
105
|
+
},
|
|
106
|
+
"payment": {
|
|
107
|
+
"publicAPIStrategy": "strict",
|
|
108
|
+
"privateAPIStrategy": "heavy",
|
|
109
|
+
"apis": ["/charge", "/refund"]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Strategy Selection
|
|
116
|
+
|
|
117
|
+
| Request Type | Strategy Used |
|
|
118
|
+
|--------------|---------------|
|
|
119
|
+
| Public API (no auth) | `publicAPIStrategy` |
|
|
120
|
+
| Private API (authenticated) | `privateAPIStrategy` |
|
|
121
|
+
|
|
122
|
+
Determined by: `req.soajs.controller.serviceParams.isAPIPublic`
|
|
123
|
+
|
|
124
|
+
## Storage Backends
|
|
125
|
+
|
|
126
|
+
### Memory (Default)
|
|
127
|
+
|
|
128
|
+
- Fast, in-process storage
|
|
129
|
+
- Lost on restart
|
|
130
|
+
- Good for single-instance deployments
|
|
131
|
+
|
|
132
|
+
### MongoDB
|
|
133
|
+
|
|
134
|
+
- Persistent storage
|
|
135
|
+
- Shared across instances
|
|
136
|
+
- Required for multi-instance deployments
|
|
137
|
+
|
|
138
|
+
Configure via `registry.custom.gateway.value.traffic.model`:
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
{
|
|
142
|
+
"traffic": {
|
|
143
|
+
"model": "mongo" // or "memory"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Rate Limit Response
|
|
149
|
+
|
|
150
|
+
When rate limit exceeded:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
HTTP/1.1 429 Too Many Requests
|
|
154
|
+
Content-Type: application/json
|
|
155
|
+
Retry-After: 45
|
|
156
|
+
X-RateLimit-Limit: 50
|
|
157
|
+
X-RateLimit-Remaining: 0
|
|
158
|
+
|
|
159
|
+
{
|
|
160
|
+
"result": false,
|
|
161
|
+
"errors": { ... }
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Response Headers
|
|
166
|
+
|
|
167
|
+
| Header | Description |
|
|
168
|
+
|--------|-------------|
|
|
169
|
+
| `X-RateLimit-Limit` | Maximum requests allowed |
|
|
170
|
+
| `X-RateLimit-Remaining` | Requests remaining in window |
|
|
171
|
+
| `Retry-After` | Seconds until window resets |
|
|
172
|
+
|
|
173
|
+
## Throttle Key Structure
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
{
|
|
177
|
+
"l1": "tenant_id",
|
|
178
|
+
"l2": "client_ip"
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Creates unique tracking per tenant per IP.
|
|
183
|
+
|
|
184
|
+
## Usage Notes
|
|
185
|
+
|
|
186
|
+
- Throttling disabled if no strategy configured
|
|
187
|
+
- Service-specific config overrides global config
|
|
188
|
+
- APIs array allows targeting specific endpoints
|
|
189
|
+
- Retries add delay before rejection
|
|
190
|
+
- MongoDB model required for horizontal scaling
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# URL Middleware
|
|
2
|
+
|
|
3
|
+
**File:** `mw/url/index.js`
|
|
4
|
+
|
|
5
|
+
**Order:** 8
|
|
6
|
+
|
|
7
|
+
The URL middleware parses the request URL and extracts service routing information.
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
- Parses URL into components (service name, version, path)
|
|
12
|
+
- Validates service exists in registry
|
|
13
|
+
- Normalizes header and query parameters (key, access_token)
|
|
14
|
+
- Creates `req.soajs.controller.serviceParams` structure
|
|
15
|
+
|
|
16
|
+
## Flow
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Incoming Request
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
┌─────────────────┐
|
|
23
|
+
│ Ensure │ if (!req.soajs.controller)
|
|
24
|
+
│ Controller │ req.soajs.controller = {}
|
|
25
|
+
└────────┬────────┘
|
|
26
|
+
│
|
|
27
|
+
▼
|
|
28
|
+
┌─────────────────┐
|
|
29
|
+
│ Parse URL │ url.parse(req.url, true)
|
|
30
|
+
└────────┬────────┘
|
|
31
|
+
│
|
|
32
|
+
▼
|
|
33
|
+
┌─────────────────┐
|
|
34
|
+
│ Extract │ service_n, service_v, service_nv
|
|
35
|
+
│ Service Info │ serviceInfo, path
|
|
36
|
+
└────────┬────────┘
|
|
37
|
+
│
|
|
38
|
+
├─── No service name? ──▶ Error 136
|
|
39
|
+
│
|
|
40
|
+
├─── Service not in registry? ──▶ Error 130
|
|
41
|
+
│
|
|
42
|
+
▼
|
|
43
|
+
┌─────────────────┐
|
|
44
|
+
│ Normalize │ key, access_token from headers/query
|
|
45
|
+
│ Auth Params │
|
|
46
|
+
└────────┬────────┘
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
next()
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## URL Parsing
|
|
53
|
+
|
|
54
|
+
**URL Format:** `/{service}/{version}/{path}`
|
|
55
|
+
|
|
56
|
+
| Component | Example | Description |
|
|
57
|
+
|-----------|---------|-------------|
|
|
58
|
+
| `service_n` | `oauth` | Service name |
|
|
59
|
+
| `service_v` | `1` | Service version (optional) |
|
|
60
|
+
| `service_nv` | `oauth/1` | Service with version |
|
|
61
|
+
| `path` | `/token` | API path |
|
|
62
|
+
|
|
63
|
+
**Examples:**
|
|
64
|
+
```
|
|
65
|
+
/oauth/token → service: oauth, version: null, path: /token
|
|
66
|
+
/oauth/1/token → service: oauth, version: 1, path: /token
|
|
67
|
+
/urac/3/user/login → service: urac, version: 3, path: /user/login
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Properties Set
|
|
71
|
+
|
|
72
|
+
| Property | Description |
|
|
73
|
+
|----------|-------------|
|
|
74
|
+
| `req.soajs.controller.serviceParams.service_n` | Service name |
|
|
75
|
+
| `req.soajs.controller.serviceParams.service_v` | Service version |
|
|
76
|
+
| `req.soajs.controller.serviceParams.service_nv` | Service with version |
|
|
77
|
+
| `req.soajs.controller.serviceParams.serviceInfo` | URL path segments array |
|
|
78
|
+
| `req.soajs.controller.serviceParams.parsedUrl` | Full parsed URL object |
|
|
79
|
+
| `req.query` | Query parameters |
|
|
80
|
+
|
|
81
|
+
## Auth Parameter Normalization
|
|
82
|
+
|
|
83
|
+
The middleware normalizes authentication parameters:
|
|
84
|
+
|
|
85
|
+
1. **Key:** `req.headers.key` ← `req.headers.key || req.query.key`
|
|
86
|
+
2. **Access Token:** `req.query.access_token` ←
|
|
87
|
+
- `req.query.access_token`
|
|
88
|
+
- `req.headers.access_token`
|
|
89
|
+
- Bearer token from `Authorization` header
|
|
90
|
+
|
|
91
|
+
## Error Codes
|
|
92
|
+
|
|
93
|
+
| Code | Description |
|
|
94
|
+
|------|-------------|
|
|
95
|
+
| 130 | Service not found in registry |
|
|
96
|
+
| 136 | Empty or missing service name |
|
|
97
|
+
|
|
98
|
+
## Usage Notes
|
|
99
|
+
|
|
100
|
+
- Throws TypeError if SOAJS middleware hasn't run first
|
|
101
|
+
- Special handling for `soajs` service name (gateway routes)
|
|
102
|
+
- Authorization header is deleted after extracting Bearer token
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Multi-Tenant Security Pipeline
|
|
2
|
+
|
|
3
|
+
The SOAJS Controller Gateway implements a comprehensive security pipeline for multi-tenant environments.
|
|
4
|
+
|
|
5
|
+
## Security Check Flow
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ MULTI-TENANT SECURITY CHECKS │
|
|
10
|
+
└─────────────────────────────────────────────────────────────────────────────────┘
|
|
11
|
+
|
|
12
|
+
Incoming Request with Key
|
|
13
|
+
│
|
|
14
|
+
▼
|
|
15
|
+
┌───────────────────┐
|
|
16
|
+
│ 1. IP Whitelist │ Check application-level IP restrictions
|
|
17
|
+
│ Validation │ FAIL → 403 Forbidden
|
|
18
|
+
└─────────┬─────────┘
|
|
19
|
+
│ PASS
|
|
20
|
+
▼
|
|
21
|
+
┌───────────────────┐
|
|
22
|
+
│ 2. Geo-Location │ Validate request origin geography
|
|
23
|
+
│ Check │ FAIL → 403 Forbidden
|
|
24
|
+
└─────────┬─────────┘
|
|
25
|
+
│ PASS
|
|
26
|
+
▼
|
|
27
|
+
┌───────────────────┐
|
|
28
|
+
│ 3. Device │ Verify device fingerprint
|
|
29
|
+
│ Fingerprint │ FAIL → 403 Forbidden
|
|
30
|
+
└─────────┬─────────┘
|
|
31
|
+
│ PASS
|
|
32
|
+
▼
|
|
33
|
+
┌───────────────────┐
|
|
34
|
+
│ 4. ACL Check │ Validate service/API access permission
|
|
35
|
+
│ │ FAIL → 403 Forbidden
|
|
36
|
+
└─────────┬─────────┘
|
|
37
|
+
│ PASS
|
|
38
|
+
▼
|
|
39
|
+
┌───────────────────┐
|
|
40
|
+
│ 5. OAuth Check │ Validate token (OAuth2 or JWT)
|
|
41
|
+
│ │ FAIL → 401 Unauthorized
|
|
42
|
+
└─────────┬─────────┘
|
|
43
|
+
│ PASS
|
|
44
|
+
▼
|
|
45
|
+
┌───────────────────┐
|
|
46
|
+
│ 6. URAC Profile │ Load user profile and groups
|
|
47
|
+
│ Resolution │ Resolve user-specific ACL
|
|
48
|
+
└─────────┬─────────┘
|
|
49
|
+
│
|
|
50
|
+
▼
|
|
51
|
+
Continue to Service
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Security Checks Detail
|
|
55
|
+
|
|
56
|
+
### 1. IP Whitelist Validation
|
|
57
|
+
|
|
58
|
+
**Middleware:** `mw/mt/utils.js`
|
|
59
|
+
|
|
60
|
+
Validates that the request IP is allowed to access the application.
|
|
61
|
+
|
|
62
|
+
- Configured per external key in the key's `geo` field
|
|
63
|
+
- Supports CIDR notation for IP ranges
|
|
64
|
+
- Also supports gateway-level whitelist via custom registry
|
|
65
|
+
|
|
66
|
+
### 2. Geo-Location Check
|
|
67
|
+
|
|
68
|
+
**Middleware:** `mw/mt/utils.js`
|
|
69
|
+
|
|
70
|
+
Validates request origin based on geographic location.
|
|
71
|
+
|
|
72
|
+
- Configured in external key's `geo` field
|
|
73
|
+
- Supports country-level restrictions
|
|
74
|
+
|
|
75
|
+
### 3. Device Fingerprint
|
|
76
|
+
|
|
77
|
+
**Middleware:** `mw/mt/utils.js`
|
|
78
|
+
|
|
79
|
+
Validates device fingerprint for mobile/app authentication.
|
|
80
|
+
|
|
81
|
+
- Configured in external key's `device` field
|
|
82
|
+
- Useful for mobile app authentication
|
|
83
|
+
|
|
84
|
+
### 4. ACL Check
|
|
85
|
+
|
|
86
|
+
**Middleware:** `mw/mt/utils.js`
|
|
87
|
+
|
|
88
|
+
Validates that the tenant has access to the requested service/API.
|
|
89
|
+
|
|
90
|
+
ACL Resolution Priority:
|
|
91
|
+
1. User-specific ACL (from URAC profile)
|
|
92
|
+
2. Application ACL (from tenant application)
|
|
93
|
+
3. Package ACL (from product package)
|
|
94
|
+
|
|
95
|
+
### 5. OAuth Check
|
|
96
|
+
|
|
97
|
+
**Middleware:** `mw/oauth/index.js`
|
|
98
|
+
|
|
99
|
+
Validates OAuth2 tokens or JWT.
|
|
100
|
+
|
|
101
|
+
- Supports OAuth2 password grant
|
|
102
|
+
- Supports JWT validation
|
|
103
|
+
- Configurable per service
|
|
104
|
+
|
|
105
|
+
### 6. URAC Profile Resolution
|
|
106
|
+
|
|
107
|
+
**Middleware:** `mw/mt/urac.js`
|
|
108
|
+
|
|
109
|
+
Loads user profile from URAC for authenticated requests.
|
|
110
|
+
|
|
111
|
+
- Resolves user groups
|
|
112
|
+
- Applies user-specific ACL overrides
|
|
113
|
+
- Handles network package override for user packages
|
|
114
|
+
|
|
115
|
+
## IP Whitelist Configuration
|
|
116
|
+
|
|
117
|
+
### Gateway-Level Whitelist
|
|
118
|
+
|
|
119
|
+
```javascript
|
|
120
|
+
// In custom registry: gateway.value.mt.whitelist
|
|
121
|
+
{
|
|
122
|
+
"mt": {
|
|
123
|
+
"whitelist": {
|
|
124
|
+
"ips": ["10.0.0.0/8", "192.168.1.0/24"],
|
|
125
|
+
"acl": true, // Skip ACL checks for whitelisted IPs
|
|
126
|
+
"oauth": true // Skip OAuth checks for whitelisted IPs
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Key-Level Restrictions
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
// In external key definition
|
|
136
|
+
{
|
|
137
|
+
"extKey": "...",
|
|
138
|
+
"env": "DEV",
|
|
139
|
+
"geo": {
|
|
140
|
+
"ips": ["192.168.1.0/24"],
|
|
141
|
+
"countries": ["US", "CA"]
|
|
142
|
+
},
|
|
143
|
+
"device": {
|
|
144
|
+
"allow": ["iOS", "Android"]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## ACL Structure
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
{
|
|
153
|
+
"serviceName": {
|
|
154
|
+
"version": {
|
|
155
|
+
"access": true, // or false, or ["group1", "group2"]
|
|
156
|
+
"apisPermission": "restricted", // "restricted" = whitelist mode
|
|
157
|
+
"get": {
|
|
158
|
+
"apis": {
|
|
159
|
+
"/api/path": {
|
|
160
|
+
"access": ["owner", "admin"] // Groups allowed
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"post": { ... },
|
|
165
|
+
"put": { ... },
|
|
166
|
+
"delete": { ... }
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Error Codes
|
|
173
|
+
|
|
174
|
+
| Code | Description |
|
|
175
|
+
|------|-------------|
|
|
176
|
+
| 150 | ACL validation failed - no access to service |
|
|
177
|
+
| 151 | ACL validation failed - no access to API |
|
|
178
|
+
| 152 | ACL validation failed - version mismatch |
|
|
179
|
+
| 153 | Geo-location validation failed |
|
|
180
|
+
| 154 | Device validation failed |
|
|
181
|
+
| 155 | IP whitelist validation failed |
|
|
182
|
+
| 401 | OAuth token invalid or expired |
|
|
183
|
+
| 403 | Access forbidden |
|