secure-gateway-sdk 1.0.0 → 1.0.1
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/README.md +3 -3
- package/index.js +28 -41
- package/package.json +2 -2
- package/server.js +22 -0
package/README.md
CHANGED
|
@@ -21,9 +21,9 @@ const app = express();
|
|
|
21
21
|
// Mount the Security Gateway to any route string (e.g. /api)
|
|
22
22
|
app.use('/api', SecurityGateway({
|
|
23
23
|
jwtSecret: 'process.env.MY_SECRET', // Required: For verifying tokens
|
|
24
|
-
authTarget: 'http
|
|
25
|
-
enclaveTarget: 'http
|
|
26
|
-
auditTarget: 'http
|
|
24
|
+
authTarget: 'http://<auth-host>:<port>',
|
|
25
|
+
enclaveTarget: 'http://<enclave-host>:<port>',
|
|
26
|
+
auditTarget: 'http://<audit-host>:<port>'
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
29
|
app.listen(3000, () => {
|
package/index.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
3
3
|
const { createSecurityMiddleware } = require('./middleware/security');
|
|
4
|
-
const { createMLSMiddleware } = require('./middleware/mls');
|
|
4
|
+
const { createMLSMiddleware } = require('./middleware/mls');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Universal Security Gateway Library (Publishable SDK)
|
|
8
|
-
* Dynamic configuration for securing any microservice architecture.
|
|
9
|
-
*
|
|
10
|
-
* @param {Object} options Configuration Object
|
|
11
|
-
* @param {string} options.jwtSecret The verification secret for Tokens
|
|
12
|
-
* @param {Array} options.routes Array defining paths, targets, and protection logic
|
|
13
8
|
*/
|
|
14
9
|
function SecurityGateway(options) {
|
|
15
10
|
const router = express.Router();
|
|
@@ -22,64 +17,49 @@ function SecurityGateway(options) {
|
|
|
22
17
|
|
|
23
18
|
if (options.routes && Array.isArray(options.routes)) {
|
|
24
19
|
options.routes.forEach(route => {
|
|
25
|
-
const proxyConfig = {
|
|
26
|
-
target: route.target,
|
|
27
|
-
changeOrigin: true
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Custom rewrite rules provided by the implementing developer
|
|
31
|
-
if (route.pathRewrite) {
|
|
32
|
-
proxyConfig.pathRewrite = route.pathRewrite;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Chain middlewares dynamically depending on if route is protected
|
|
36
20
|
const middlewares = [];
|
|
21
|
+
|
|
37
22
|
if (route.protected) {
|
|
38
|
-
// Step 1: Extract and verify JWT
|
|
39
23
|
middlewares.push(verifyToken);
|
|
40
|
-
|
|
41
|
-
// Step 2: Inject Bell-LaPadula rules if clearance is specified for the route!
|
|
42
24
|
if (route.requiredClearance) {
|
|
43
25
|
middlewares.push(createMLSMiddleware(route.requiredClearance));
|
|
44
|
-
// middlewares.push('S');
|
|
45
26
|
}
|
|
46
27
|
}
|
|
47
|
-
|
|
48
|
-
// Step 3: Physically Forward the Request
|
|
28
|
+
|
|
49
29
|
if (route.useSecureChannel) {
|
|
50
30
|
const EnclaveClient = require('./lib/enclave-client');
|
|
51
|
-
|
|
31
|
+
// Security params are now pulled directly from the ROUTE config!
|
|
32
|
+
const enclaveClient = new EnclaveClient(route.target, route.mrenclave);
|
|
52
33
|
const BLSAuditSim = require('./lib/bls');
|
|
53
|
-
const blsAudit = new BLSAuditSim(
|
|
34
|
+
const blsAudit = new BLSAuditSim(route.blsPrivateKey);
|
|
54
35
|
|
|
55
|
-
// Express json parser for the proxy to read the body before encryption
|
|
56
36
|
middlewares.push(express.json());
|
|
57
37
|
middlewares.push(async (req, res) => {
|
|
58
38
|
try {
|
|
59
39
|
const payload = req.body && Object.keys(req.body).length > 0 ? req.body : { action: "read_data" };
|
|
60
40
|
const token = req.headers['authorization']?.split(' ')[1];
|
|
61
|
-
|
|
62
|
-
// Execute over ECDH secure channel
|
|
41
|
+
|
|
63
42
|
const result = await enclaveClient.execute(payload, token);
|
|
64
|
-
|
|
65
|
-
// Generate Audit Log
|
|
43
|
+
|
|
66
44
|
const logEntry = {
|
|
67
45
|
timestamp: new Date().toISOString(),
|
|
68
|
-
user: req.user.
|
|
69
|
-
clearance: req.user
|
|
70
|
-
action: '
|
|
46
|
+
user: req.user?.username || req.user?.sub || 'anonymous',
|
|
47
|
+
clearance: req.user?.clearance || 'N/A',
|
|
48
|
+
action: route.actionName || 'gateway_access',
|
|
49
|
+
resource: route.path,
|
|
71
50
|
status: 'SUCCESS'
|
|
72
51
|
};
|
|
52
|
+
|
|
73
53
|
const sigData = blsAudit.signAndAggregate(logEntry);
|
|
74
54
|
Object.assign(logEntry, sigData);
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
if (
|
|
78
|
-
fetch(
|
|
55
|
+
|
|
56
|
+
// Audit target is now also route-specific!
|
|
57
|
+
if (route.auditUrl) {
|
|
58
|
+
fetch(route.auditUrl + '/log', {
|
|
79
59
|
method: 'POST',
|
|
80
60
|
headers: { 'Content-Type': 'application/json' },
|
|
81
61
|
body: JSON.stringify(logEntry)
|
|
82
|
-
}).catch(
|
|
62
|
+
}).catch(() => {});
|
|
83
63
|
}
|
|
84
64
|
|
|
85
65
|
res.json(result);
|
|
@@ -88,20 +68,27 @@ function SecurityGateway(options) {
|
|
|
88
68
|
}
|
|
89
69
|
});
|
|
90
70
|
} else {
|
|
71
|
+
const proxyConfig = {
|
|
72
|
+
target: route.target,
|
|
73
|
+
changeOrigin: true
|
|
74
|
+
};
|
|
75
|
+
if (route.pathRewrite) proxyConfig.pathRewrite = route.pathRewrite;
|
|
91
76
|
middlewares.push(createProxyMiddleware(proxyConfig));
|
|
92
77
|
}
|
|
93
78
|
|
|
94
79
|
router.use(route.path, ...middlewares);
|
|
95
|
-
|
|
96
|
-
console.log(`[SecurityGateway] Shield mounted: ${route.path} -> ${route.target} (Protected: ${!!route.protected}, MLS: ${route.requiredClearance || 'None'})`);
|
|
80
|
+
console.log(`[SecurityGateway] Shield mounted: ${route.path} -> ${route.target}`);
|
|
97
81
|
});
|
|
98
82
|
}
|
|
99
83
|
|
|
100
84
|
return router;
|
|
101
85
|
}
|
|
102
86
|
|
|
87
|
+
const { SecureChannel } = require('./lib/crypto');
|
|
88
|
+
|
|
103
89
|
module.exports = {
|
|
104
90
|
SecurityGateway,
|
|
105
91
|
createSecurityMiddleware,
|
|
106
|
-
createMLSMiddleware
|
|
92
|
+
createMLSMiddleware,
|
|
93
|
+
SecureChannel
|
|
107
94
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "secure-gateway-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"scripts": {
|
|
5
|
-
"dev": "
|
|
5
|
+
"dev": "node server.js"
|
|
6
6
|
},
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"cors": "^2.8.6",
|
package/server.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require('dotenv').config({ path: '../.env' });
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const { SecurityGateway } = require('./index');
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
const PORT = process.env.PROXY_PORT || 3000;
|
|
7
|
+
|
|
8
|
+
const gatewayRoutes = require('../config/gateway-routes.json');
|
|
9
|
+
|
|
10
|
+
// Initialize the Security Gateway as a standalone server
|
|
11
|
+
app.use('/api', SecurityGateway({
|
|
12
|
+
jwtSecret: process.env.JWT_SECRET,
|
|
13
|
+
routes: gatewayRoutes
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
app.get('/', (req, res) => {
|
|
17
|
+
res.json({ message: 'Security Gateway Standalone Server is running.' });
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
app.listen(PORT, () => {
|
|
21
|
+
console.log(`[Proxy] Standalone Gateway running on port ${PORT}`);
|
|
22
|
+
});
|