技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
finta-security-basics【数据与研究】Secure Finta fundraising data and investor information. Trigger with phrases like "finta security", "finta data privacy".
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: finta-security-basics description: 'Secure Finta fundraising data and investor information.
Trigger with phrases like "finta security", "finta data privacy".
' allowed-tools: Read, Grep version: 1.7.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:
Finta manages fundraising pipelines containing investor contact information, term sheet details, valuation data, cap table snapshots, and deal room documents. A breach exposes confidential fundraising strategy, investor relationships, and financial terms that could damage competitive positioning. Protect API credentials, deal room access controls, and any integration that syncs investor data to external CRMs or spreadsheets.
function createFintaClient(): { apiKey: string; baseUrl: string } {
const apiKey = process.env.FINTA_API_KEY;
if (!apiKey) {
throw new Error("Missing FINTA_API_KEY — store in secrets manager, never in code");
}
// Finta keys access investor contacts and financial terms — treat as highly sensitive
console.log("Finta client initialized (key suffix:", apiKey.slice(-4), ")");
return { apiKey, baseUrl: "https://api.trustfinta.com/v1" };
}
import crypto from "crypto";
import { Request, Response, NextFunction } from "express";
function verifyFintaWebhook(req: Request, res: Response, next: NextFunction): void {
const signature = req.headers["x-finta-signature"] as string;
const secret = process.env.FINTA_WEBHOOK_SECRET!;
const expected = crypto.createHmac("sha256", secret).update(req.body).digest("hex");
if (!signature || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
res.status(401).send("Invalid signature");
return;
}
next();
}
import { z } from "zod";
const InvestorContactSchema = z.object({
investor_id: z.string().uuid(),
firm_name: z.string().min(1).max(200),
contact_email: z.string().email(),
deal_stage: z.enum(["prospect", "contacted", "meeting", "term_sheet", "closed", "passed"]),
check_size: z.number().positive().optional(),
valuation_cap: z.number().positive().optional(),
});
function validateInvestorData(data: unknown) {
return InvestorContactSchema.parse(data);
}
const FINTA_SENSITIVE_FIELDS = ["valuation_cap", "check_size", "term_sheet_url", "cap_table", "investor_email", "phone"];
function redactFintaLog(record: Record<string, unknown>): Record<string, unknown> {
const redacted = { ...record };
for (const field of FINTA_SENSITIVE_FIELDS) {
if (field in redacted) redacted[field] = "[REDACTED]";
}
return redacted;
}
| Vulnerability | Risk | Mitigation |
|---|---|---|
| Leaked API key | Full access to investor pipeline and deal terms | Secrets manager + rotation |
| Overly broad deal room access | Confidential terms exposed to wrong investors | Per-investor permission scoping |
| Unencrypted pipeline exports | Financial strategy leaked via CSV files | GPG encryption + .gitignore |
| Stale investor access | Former prospects retain document access | Post-round access review |
| CRM sync without redaction | Valuation data leaks to third-party CRM | Field-level redaction before sync |
Produce a short security record containing the system owner, approved integrations, role-review date, credential location reference (never the secret), and any access removals or rotations performed. Logs and incident reports should use redacted identifiers and aggregate counts only.
For a sandbox workflow, create two fictitious investor records, export only stage and anonymized amount ranges, and confirm that the destination receives neither emails nor document links. If the webhook signature check fails, acknowledge nothing downstream, retain a redacted failure receipt, and investigate the source before retrying.
See finta-prod-checklist.