用Spring Boot搭建企业AI安全网关:输入审核、PII脱敏、输出校验与审计

发布时间:2026/8/2 14:48:30

用Spring Boot搭建企业AI安全网关:输入审核、PII脱敏、输出校验与审计 文章摘要企业接入多个大模型后若每个业务系统自行处理Moderation、敏感信息脱敏、Prompt Injection、工具权限和日志审计安全策略很快会失控。本文使用Spring Boot设计一个统一AI安全网关通过标准请求对象串联身份校验、输入长度限制、PII检测、内容审核、Prompt Injection检测、模型代理、输出DLP和审计日志并提供可扩展接口与核心代码骨架。一、网关的目标统一链路业务系统 → AI安全网关 → 模型Provider网关负责身份与租户请求配额模型白名单输入审核PII检测与脱敏Prompt Injection检测工具白名单输出校验成本与审计统一错误码。业务系统负责业务场景用户体验领域权限最终业务动作。安全网关不能代替业务权限但可以提供统一执行点。二、项目结构ai-security-gateway ├── controller │ └── AiGatewayController.java ├── model │ ├── AiGatewayRequest.java │ ├── AiGatewayResponse.java │ └── SecurityDecision.java ├── security │ ├── SecurityPipeline.java │ ├── InputLengthGuard.java │ ├── PiiGuard.java │ ├── ModerationGuard.java │ ├── PromptInjectionGuard.java │ └── OutputGuard.java ├── provider │ ├── ModelProvider.java │ └── SpringAiModelProvider.java ├── audit │ ├── AuditEvent.java │ └── AuditService.java └── exception └── GatewayExceptionHandler.java三、统一请求对象publicrecordAiGatewayRequest(StringrequestId,StringtenantId,StringuserId,Stringscenario,StringmodelTier,Stringmessage,MapString,Objectcontext,SetStringrequestedTools){}注意tenantId和userId不应直接信任请求Body应从认证Token或网关身份上下文写入。对外请求可以不包含这两个字段Controller负责补全。四、统一安全动作publicenumSecurityAction{ALLOW,MASK_AND_ALLOW,SAFE_MODE,HUMAN_REVIEW,REJECT}publicrecordSecurityDecision(SecurityActionaction,SetStringreasons,StringsanitizedText,SetSensitiveEntitysensitiveEntities,doubleriskScore){publicbooleanallowed(){returnactionSecurityAction.ALLOW||actionSecurityAction.MASK_AND_ALLOW||actionSecurityAction.SAFE_MODE;}}五、定义Guard接口publicinterfaceInputGuard{GuardResultevaluate(GuardContextcontext,Stringtext);}publicrecordGuardResult(booleanpassed,SecurityActionrecommendedAction,StringtransformedText,SetStringreasons,doublescore){}每个Guard只做一件事SecurityPipeline负责汇总。六、输入长度GuardComponentpublicclassInputLengthGuardimplementsInputGuard{privatestaticfinalintMAX_CHARS50_000;OverridepublicGuardResultevaluate(GuardContextcontext,Stringtext){if(textnull||text.isBlank()){returnnewGuardResult(false,SecurityAction.REJECT,text,Set.of(EMPTY_INPUT),1.0);}if(text.length()MAX_CHARS){returnnewGuardResult(false,SecurityAction.REJECT,text,Set.of(INPUT_TOO_LONG),1.0);}returnpassed(text);}}长度限制应按场景配置而不是全局固定。七、PII Guard实体对象publicrecordSensitiveEntity(Stringtype,intstart,intend,Stringreplacement,Stringhash){}基础检测ComponentpublicclassPiiGuardimplementsInputGuard{privatestaticfinalPatternMOBILEPattern.compile((?!\\d)1[3-9]\\d{9}(?!\\d));OverridepublicGuardResultevaluate(GuardContextcontext,Stringtext){MatchermatcherMOBILE.matcher(text);Stringmaskedmatcher.replaceAll(MOBILE);if(!masked.equals(text)){returnnewGuardResult(true,SecurityAction.MASK_AND_ALLOW,masked,Set.of(MOBILE_DETECTED),0.7);}returnpassed(text);}}生产环境还应校验身份证校验位支持企业自定义字段保留受控映射区分允许使用和禁止外发支持中文姓名与地址NER。八、Moderation GuardComponentpublicclassModerationGuardimplementsInputGuard{privatefinalModerationModelmoderationModel;publicModerationGuard(ModerationModelmoderationModel){this.moderationModelmoderationModel;}OverridepublicGuardResultevaluate(GuardContextcontext,Stringtext){ModerationResponseresponsemoderationModel.call(newModerationPrompt(text));ModerationSummarysummarymapResponse(response);if(summary.highRisk()){returnnewGuardResult(false,SecurityAction.REJECT,text,summary.categories(),summary.maxScore());}returnpassed(text);}}不要让业务层直接解析Provider特定结构。九、Prompt Injection Guard使用规则和模型组合ComponentpublicclassPromptInjectionGuardimplementsInputGuard{privatefinalListPatternpatternsList.of(Pattern.compile(忽略.{0,20}(规则|指令|提示词)),Pattern.compile((输出|打印).{0,20}系统提示词),Pattern.compile((调用|执行).{0,20}(工具|命令)));OverridepublicGuardResultevaluate(GuardContextcontext,Stringtext){booleanmatchedpatterns.stream().anyMatch(p-p.matcher(text).find());if(matched){returnnewGuardResult(false,SecurityAction.HUMAN_REVIEW,text,Set.of(PROMPT_INJECTION_SUSPECTED),0.75);}returnpassed(text);}}不能只检测中文固定短语还需要对抗测试和语义分类。十、SecurityPipelineServicepublicclassSecurityPipeline{privatefinalListInputGuardguards;publicSecurityPipeline(ListInputGuardguards){this.guardsguards;}publicSecurityDecisionevaluateInput(GuardContextcontext,StringoriginalText){StringcurrentTextoriginalText;SetStringreasonsnewLinkedHashSet();SecurityActionactionSecurityAction.ALLOW;doublemaxRisk0.0;for(InputGuardguard:guards){GuardResultresultguard.evaluate(context,currentText);reasons.addAll(result.reasons());maxRiskMath.max(maxRisk,result.score());if(result.transformedText()!null){currentTextresult.transformedText();}actionmerge(action,result.recommendedAction());if(actionSecurityAction.REJECT){break;}}returnnewSecurityDecision(action,reasons,currentText,Set.of(),maxRisk);}}动作优先级REJECT HUMAN_REVIEW SAFE_MODE MASK_AND_ALLOW ALLOW十一、模型Provider抽象publicinterfaceModelProvider{ModelResultgenerate(SafeAiRequestrequest);}ServicepublicclassSpringAiModelProviderimplementsModelProvider{privatefinalChatClientchatClient;OverridepublicModelResultgenerate(SafeAiRequestrequest){StringcontentchatClient.prompt().system(request.systemPrompt()).user(request.sanitizedMessage()).call().content();returnnewModelResult(content);}}Provider层不应绕过安全Pipeline。十二、模型白名单publicModelTierresolveModel(StringtenantId,Stringscenario,StringrequestedTier){ModelPolicypolicypolicyRepository.load(tenantId,scenario);if(!policy.allowedTiers().contains(requestedTier)){thrownewModelNotAllowedException();}returnModelTier.valueOf(requestedTier);}防止业务系统随意使用高成本或未审批模型。十三、工具白名单请求中的工具集合必须与服务端策略求交集SetStringallowedToolstoolPolicyService.allowedTools(tenantId,userId,scenario);SetStringeffectiveToolsrequestedTools.stream().filter(allowedTools::contains).collect(Collectors.toUnmodifiableSet());不要直接把客户端传来的工具名注册给ChatClient。十四、输出Guard输出检查PII Moderation 系统提示词泄露 密钥格式 证据引用 业务禁用表达接口publicinterfaceOutputGuard{GuardResultevaluate(GuardContextcontext,StringmodelOutput);}高风险输出可以拒绝脱敏重写转人工返回安全模板。不要让同一个模型无条件“自我审核”后直接放行。十五、Controller完整流程PostMapping(/v1/ai/generate)publicAiGatewayResponsegenerate(Authenticationauthentication,ValidRequestBodyGatewayInputinput){AuthenticatedUseruseridentityService.current(authentication);AiGatewayRequestrequestrequestFactory.create(user,input);SecurityDecisioninputDecisionsecurityPipeline.evaluateInput(GuardContext.from(request),request.message());auditService.recordInputDecision(request,inputDecision);if(!inputDecision.allowed()){thrownewAiSecurityException(inputDecision.action());}ModelResultmodelResultmodelProvider.generate(safeRequestFactory.create(request,inputDecision));SecurityDecisionoutputDecisionsecurityPipeline.evaluateOutput(GuardContext.from(request),modelResult.content());if(!outputDecision.allowed()){thrownewAiOutputBlockedException();}returnresponseFactory.create(request,outputDecision.sanitizedText());}十六、审计事件publicrecordAuditEvent(StringrequestId,StringtenantId,StringuserIdHash,Stringscenario,Stringmodel,StringinputHash,intinputLength,SecurityActioninputAction,SecurityActionoutputAction,SetStringreasons,longlatencyMs,InstantcreatedAt){}默认不要保存完整输入输出。敏感原文如需留存应进入单独加密审计库。十七、统一错误码AI_INPUT_BLOCKED AI_OUTPUT_BLOCKED AI_HUMAN_REVIEW_REQUIRED AI_MODEL_NOT_ALLOWED AI_TOOL_NOT_ALLOWED AI_SECURITY_SERVICE_UNAVAILABLE AI_RATE_LIMITED前端不要看到内部风险规则和阈值。十八、失败策略Moderation不可用高风险场景Fail Closed低风险内部场景进入SAFE_MODEDLP不可用含敏感数据的业务应拒绝或转人工。审计服务不可用高风险工具调用应阻断普通问答可以写入本地可靠队列后继续。十九、可观测性指标ai_gateway_requests_total ai_gateway_blocked_total ai_gateway_review_total ai_gateway_pii_detected_total ai_gateway_injection_detected_total ai_gateway_security_latency ai_gateway_model_latency ai_gateway_output_blocked_total标签不要使用原始userId或Prompt避免高基数和隐私泄露。二十、生产补齐项Redis配额OPA或Cedar策略引擎OpenTelemetry密钥管理模型路由流式输出安全文件上传沙箱多模态审核人工审核后台对抗测试集灰度规则发布。总结企业AI安全网关的核心价值是把分散在各业务系统中的控制统一为身份 → 输入安全 → 数据脱敏 → 模型与工具策略 → 输出安全 → 审计它不替代业务权限但可以成为所有模型调用必须经过的统一安全执行点。

相关新闻