feat(ops-auth): add scoped API token auth across ops endpoints
This commit is contained in:
@@ -2,6 +2,7 @@ import * as plugins from '../../plugins.js';
|
||||
import type { OpsServer } from '../classes.opsserver.js';
|
||||
import * as interfaces from '../../../ts_interfaces/index.js';
|
||||
import { MetricsManager } from '../../monitoring/index.js';
|
||||
import { requireOpsAuth } from '../helpers/auth.js';
|
||||
|
||||
export class SecurityHandler {
|
||||
constructor(private opsServerRef: OpsServer) {
|
||||
@@ -17,6 +18,7 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetSecurityMetrics>(
|
||||
'getSecurityMetrics',
|
||||
async (dataArg, toolsArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
||||
const metrics = await this.collectSecurityMetrics();
|
||||
return {
|
||||
metrics: {
|
||||
@@ -43,6 +45,7 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetActiveConnections>(
|
||||
'getActiveConnections',
|
||||
async (dataArg, toolsArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
||||
const connections = await this.getActiveConnections(dataArg.protocol, dataArg.state);
|
||||
const connectionInfos: interfaces.data.IConnectionInfo[] = connections.map(conn => ({
|
||||
id: conn.id,
|
||||
@@ -82,6 +85,7 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetNetworkStats>(
|
||||
'getNetworkStats',
|
||||
async (dataArg, toolsArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'stats:read' });
|
||||
// Get network stats from MetricsManager if available
|
||||
if (this.opsServerRef.dcRouterRef.metricsManager) {
|
||||
const networkStats = await this.opsServerRef.dcRouterRef.metricsManager.getNetworkStats();
|
||||
@@ -136,6 +140,7 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetRateLimitStatus>(
|
||||
'getRateLimitStatus',
|
||||
async (dataArg, toolsArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
||||
const status = await this.getRateLimitStatus(dataArg.domain, dataArg.ip);
|
||||
const limits: interfaces.data.IRateLimitInfo[] = status.limits.map(limit => ({
|
||||
domain: limit.identifier,
|
||||
@@ -161,7 +166,8 @@ export class SecurityHandler {
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListSecurityBlockRules>(
|
||||
'listSecurityBlockRules',
|
||||
async () => {
|
||||
async (dataArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
return { rules: manager ? await manager.listBlockRules() : [] };
|
||||
},
|
||||
@@ -171,7 +177,8 @@ export class SecurityHandler {
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListIpIntelligence>(
|
||||
'listIpIntelligence',
|
||||
async () => {
|
||||
async (dataArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
return { records: manager ? await manager.listIpIntelligence() : [] };
|
||||
},
|
||||
@@ -181,7 +188,8 @@ export class SecurityHandler {
|
||||
router.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetCompiledSecurityPolicy>(
|
||||
'getCompiledSecurityPolicy',
|
||||
async () => {
|
||||
async (dataArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
return {
|
||||
policy: manager
|
||||
@@ -196,6 +204,7 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListSecurityPolicyAudit>(
|
||||
'listSecurityPolicyAudit',
|
||||
async (dataArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'security:read' });
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
return { events: manager ? await manager.listAuditEvents(dataArg.limit || 100) : [] };
|
||||
},
|
||||
@@ -208,6 +217,10 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateSecurityBlockRule>(
|
||||
'createSecurityBlockRule',
|
||||
async (dataArg) => {
|
||||
const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
|
||||
scope: 'security:write',
|
||||
requireAdminIdentity: true,
|
||||
});
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
||||
const rule = await manager.createBlockRule({
|
||||
@@ -216,7 +229,7 @@ export class SecurityHandler {
|
||||
matchMode: dataArg.matchMode,
|
||||
reason: dataArg.reason,
|
||||
enabled: dataArg.enabled,
|
||||
}, dataArg.identity.userId);
|
||||
}, auth.userId);
|
||||
return { success: true, rule };
|
||||
},
|
||||
),
|
||||
@@ -226,6 +239,10 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateSecurityBlockRule>(
|
||||
'updateSecurityBlockRule',
|
||||
async (dataArg) => {
|
||||
const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
|
||||
scope: 'security:write',
|
||||
requireAdminIdentity: true,
|
||||
});
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
||||
const rule = await manager.updateBlockRule(dataArg.id, {
|
||||
@@ -233,7 +250,7 @@ export class SecurityHandler {
|
||||
matchMode: dataArg.matchMode,
|
||||
reason: dataArg.reason,
|
||||
enabled: dataArg.enabled,
|
||||
}, dataArg.identity.userId);
|
||||
}, auth.userId);
|
||||
return rule ? { success: true, rule } : { success: false, message: 'Rule not found' };
|
||||
},
|
||||
),
|
||||
@@ -243,9 +260,13 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteSecurityBlockRule>(
|
||||
'deleteSecurityBlockRule',
|
||||
async (dataArg) => {
|
||||
const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
|
||||
scope: 'security:write',
|
||||
requireAdminIdentity: true,
|
||||
});
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
||||
const success = await manager.deleteBlockRule(dataArg.id, dataArg.identity.userId);
|
||||
const success = await manager.deleteBlockRule(dataArg.id, auth.userId);
|
||||
return { success, message: success ? undefined : 'Rule not found' };
|
||||
},
|
||||
),
|
||||
@@ -255,6 +276,10 @@ export class SecurityHandler {
|
||||
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_RefreshIpIntelligence>(
|
||||
'refreshIpIntelligence',
|
||||
async (dataArg) => {
|
||||
await requireOpsAuth(this.opsServerRef, dataArg, {
|
||||
scope: 'security:write',
|
||||
requireAdminIdentity: true,
|
||||
});
|
||||
const manager = this.opsServerRef.dcRouterRef.securityPolicyManager;
|
||||
if (!manager) return { success: false, message: 'Security policy manager not initialized' };
|
||||
const record = await manager.refreshIpIntelligence(dataArg.ipAddress);
|
||||
|
||||
Reference in New Issue
Block a user