mcpField
M
matlab-secure-credentials

matlab-secure-credentials

github.com/matlab安全1.2k39 次安装1 天前更新
代码仓库

关于 matlab-secure-credentials

此 MATLAB 技能指导开发者使用 MATLAB Vault 安全存储、读取并传递 API 密钥、令牌和密码。它还说明了 CI 等无交互场景下的凭据加载方式,以及避免将秘密写入代码或配置的做法。

主要功能

  1. 01使用 MATLAB Vault 管理凭据
  2. 02通过 setSecret 与 getSecret 存取
  3. 03使用 secretID 传递凭据引用
  4. 04通过 importSecrets 批量导入
  5. 05区分 Vault 与环境变量的适用场景

适用场景

  1. 01为 REST API 调用保存令牌
  2. 02为数据库或 SFTP 连接提供凭据
  3. 03在 CI 或定时任务中加载秘密
  4. 04重构代码以避免硬编码凭据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-secure-credentials

安装后在 Claude Code 中输入/matlab-secure-credentials确认已加载。

附带文件manifest.yaml

详细介绍

在 MATLAB 中安全处理凭据

使用内置于 MATLAB 的加密存储 MATLAB Vault 来管理 API 密钥、令牌、密码和口令,而不要将它们硬编码。本技能涵盖凭据本身——存储、检索凭据,并将其传入与任何需要身份验证的服务建立的连接。

适用场景

  • 从 MATLAB 连接任何需要身份验证的服务或连接,例如 REST API、数据库、云存储、SFTP/FTP 服务、消息队列或其他服务。
  • 任何处理 API 密钥、Bearer 令牌、密码或 SSH 密钥口令的代码。
  • 编写需要凭据、且运行时没有用户在场的 CI、批处理或定时 MATLAB 程序。
  • 重构凭据处理代码,或持久化包含机密信息的配置。
  • 用户要求“不要把凭据放进代码”“不要提交机密信息”或“用安全的方式处理”。

不适用场景

  • 编写连接、查询或传输逻辑,但不涉及凭据(例如公共 API 或本地文件);或在数据进入表或时间表后清理、转换或聚合数据——请使用相关的数据导入技能(例如 matlab-analyze-data、matlab-use-database)。
  • 集成第三方机密管理器(HashiCorp Vault、AWS Secrets Manager、Azure Key Vault)——不在本技能范围内。
  • 操作系统级或非 MATLAB 的密钥管理。

决策指南:选择哪种机制

根据凭据的提供方式选择机制,不要凭习惯决定。

情况使用不要使用
凭据需要存储并在不同会话中重复使用调用一次 setSecret,然后在使用时调用 getSecret硬编码;自行编写配置文件
需要一次加载一组凭据(交互式设置,或非交互式、CI、无头或定时运行)使用 importSecrets 从机密文件填充保管库,然后调用 getSecret;或者在 CI 中,使用 getenv 获取运行器注入的值在无头作业中调用 setSecret——它仅支持交互式使用
函数接受调用方提供的凭据secretID(指向机密的引用,而不是机密值)将机密值存入结构体字段或参数
凭据本身就是进程环境变量,例如 CI 注入的机密,或 AWS_ACCESS_KEY_ID 这类云 SDK 约定变量getenv——这是正确的做法无故将其复制到保管库中

原则是不要硬编码机密信息,而不是“绝不使用环境变量”。如果机密已经是进程环境变量,getenv 就是正确的工具;对于你自己存储的凭据,默认应使用保管库。

工作流

  1. 确定机制,使用上面的决策指南。
  2. 存储或填充凭据:
    • 单个机密,交互式操作:setSecret("MyApiToken")(MATLAB 会提示输入值——切勿将值作为参数传入;该函数只接受名称)。
    • 一次加载一组机密:importSecrets("secrets.env") 会在没有提示的情况下将名称和值加载到保管库中——交互式设置和非交互式/CI 场景都适用。
  3. 在使用时检索:调用 getSecret("MyApiToken");也可以将 secretID("MyApiToken") 传给接受该参数的 API(这些 API 会在调用时解析它,因此机密值不会存入变量)。
  4. 将其接入连接——请参阅下方的模式。
  5. 验证:在读取或移除机密前,使用 isSecret("MyApiToken") 检查,并确认脚本、日志或任何已保存文件中都没有出现机密值。

主要功能

功能用途起始版本
setSecret向保管库添加密钥;交互式——提示输入值,只接受名称(更新时设置 Overwrite=true)R2024a
getSecret检索密钥值(返回字符串标量)R2024a
isSecret检查是否存在指定名称的密钥R2024a
listSecrets列出已存储密钥的名称R2024a
removeSecret从保管库删除密钥(没有 deleteSecret)R2024a
setSecretMetadata为密钥附加元数据(例如过期日期、所有者)R2024a
getSecretMetadata将密钥的元数据读取为字典R2024a
secretID携带密钥名称而非其值的引用对象;weboptions 和 matlab.net.http.Credentials 均接受此对象R2025a
importSecrets将文件中的一组密钥加载到保管库(不提示)R2026a

使用模式

存储一次,使用时检索
% One-time, at the MATLAB prompt (prompts for the value — do NOT type the secret in code):
setSecret("MyApiToken");

% In your script, read it only where needed:
token = getSecret("MyApiToken");

也可以记录过期时间等元数据,以便调用方在使用前检查密钥是否仍然有效:

% Metadata values are stored in a dictionary; wrap each value in a cell:
setSecretMetadata("MyApiToken", dictionary("Expires", {datetime(2026,12,31)}));

md = getSecretMetadata("MyApiToken");
expiry = md{"Expires"};            % {} indexing returns the stored value
if expiry < datetime("today")
    error("MyApiToken expired on %s — rotate it with setSecret(...,Overwrite=true).", expiry);
end
token = getSecret("MyApiToken");
轮换或更新密钥

setSecret(...,Overwrite=true) 会替换现有密钥的值,这是轮换凭据的常用方法(例如定期替换,或在过期后替换为新值)。如果不设置 Overwrite,setSecret 在名称已存在时会报错。

setSecret("MyApiToken", Overwrite=true);   % prompts for the new value
使用 bearer token 进行 REST 调用

从保管库获取 token,并将其设置在 Authorization 标头中。

token = getSecret("MyApiToken");
opts = weboptions( ...
    HeaderFields = ["Authorization", "Bearer " + token], ...
    ContentType  = "json");
data = webread("https://api.example.com/v1/data", opts);

对于基本身份验证,将 secretID 传给 weboptions,这样值会在请求时解析,不会存放在变量中:

username = getenv("API_USER");   % REPLACE: your service-account user name
opts = weboptions(Username=username, Password=secretID("MyApiPassword"));
data = webread("https://api.example.com/v1/data", opts);

对于更底层的请求,matlab.net.http.Credentials 也接受 secretID:

cred = matlab.net.http.Credentials(Password=secretID("MyApiPassword"));
使用受密码保护密钥的 SFTP
keyFile = fullfile(userpath, "id_rsa");   % REPLACE: path to your private key
s = sftp("sftp.example.com", "reportuser", ...
    PrivateKeyFile       = keyFile, ...
    PrivateKeyPassphrase = getSecret("SftpKeyPassphrase"));
c = onCleanup(@() close(s));
localPaths  = mget(s, "/reports/nightly.csv", tempdir);
reportTable = readtable(localPaths{1});

使用密码验证而非密钥:

s = sftp("sftp.example.com", "reportuser", Password=getSecret("SftpPassword"));
数据库连接

将密码存储在保管库中,并在连接时读取。将主机、端口和数据库保存在代码中;将凭据单独保管。

conn = postgresql("svc-account", getSecret("PgPassword"), ...
    Server       = "db-prod-01", ...
    PortNumber   = 5432, ...
    DatabaseName = "analytics");
c = onCleanup(@() close(conn));
tables = sqlfind(conn, "");

若要创建可复用、可共享的设置,可通过 Database Explorer 应用或 databaseConnectionOptions + saveAsDataSource 一次性保存数据源,然后按名称连接,并从保管库提供密码:

conn = postgresql("analyticsDataSource", "svc-account", getSecret("PgPassword"));
云存储(S3 / Azure Blob / GCS)

MATLAB 的文件 I/O(readtable、datastore 等)可直接读取云 URI,并从 SDK 的环境变量中获取凭据。使用显式密钥时,应从保管库获取密钥并设置 SDK 所需的环境变量;在云基础设施上运行时,优先使用附加的 IAM 角色,不设置任何内容。

% Explicit keys held in the vault -> set the SDK env vars from getSecret:
setenv("AWS_ACCESS_KEY_ID",     getSecret("AwsAccessKeyId"));
setenv("AWS_SECRET_ACCESS_KEY", getSecret("AwsSecretAccessKey"));
setenv("AWS_DEFAULT_REGION",    "us-east-1");   % REPLACE: bucket region
T = readtable("s3://acme-data/prices/latest.csv");

如果代码在 EC2 实例或启用了角色的环境中运行,则完全跳过密钥——IAM 角色会提供凭据,无需将密钥存放在任何地方。

将凭据传入函数

函数接受调用方提供的凭据时,应传递 secretID(引用),而不是密钥值。只有在调用 getSecret 时,引用才会解析为密钥。

构建配置——其中携带的是引用,而非 token:

config = struct( ...
    "BaseUrl", "https://api.example.com/v1", ...
    "Token",   secretID("MyApiToken"));

在函数内部使用配置——仅在实际使用时解析密钥:

function report = fetchReport(config)
    arguments
        config (1,1) struct
    end
    token = getSecret(config.Token.Name);
    opts  = weboptions(HeaderFields = ["Authorization", "Bearer " + token]);
    report = webread(config.BaseUrl + "/report", opts);
end
一次加载一组密钥(设置或 CI)

importSecrets 无需提示,即可将密钥文件中的名称和对应值加载到保管库——既适用于一次性的交互式设置,也适用于无头作业(此类作业无法使用仅限交互式的 setSecret)。

% secrets.env — a dotenv file (e.g. from CI secret storage), never committed — with lines like:
%   MyApiToken=abc123
%   PgPassword=hunter2
importSecrets("secrets.env");     % FileType="auto" (default) detects the dotenv format
token = getSecret("MyApiToken");

如果运行器直接将凭据作为进程环境变量注入,而非通过文件注入,则应使用 getenv("MY_TOKEN") 读取,无需使用保管库。

约定

  • 始终:默认使用保险库(setSecret/getSecret)存储凭据;调用 removeSecret 前先检查 isSecret。
  • 始终:一次加载多个密钥,或在任何无头/CI 环境中加载密钥时,使用 importSecrets,而不是 setSecret。
  • 切勿:在 .m 文件中硬编码密钥,或将密钥值写入结构体或日志中 — 应改为传递 secretID 引用。
  • 优先:如果 API 接受引用,则向 weboptions/Credentials 传递 secretID(...),而不是通过 getSecret 获取密钥值。
  • 如果凭据确实是进程环境变量(CI 密钥、云 SDK 惯例),使用环境变量没有问题 — 不要矫枉过正地改用保险库,因为这样并无益处。

常见错误

错误错误原因正确做法
在 .m 文件中硬编码令牌/密码会泄露到版本控制中;轮换困难从保险库调用 getSecret("Name")
将密钥值写入结构体字段或函数传递的参数中明文密钥会离开保险库传递 secretID 引用;使用时通过 getSecret 获取密钥
在 CI/批处理/计划任务中调用 setSecret仅支持交互式使用 — 无法输入值使用 importSecrets 以非交互方式填充保险库
调用 deleteSecret不存在此函数调用 removeSecret("Name"),并先检查 isSecret
使用 save() 将凭据保存到 .mat 文件,再使用 load() 读回会将明文密钥写入磁盘,且不加密,往往还会提交到版本控制中将密钥值保存在保险库中;仅持久化 secretID 引用,并在使用时通过 getSecret 获取密钥

错误及其含义

错误标识符发生时机修复方法
MATLAB:authnz:secretapis:KeyAlreadyExists — "名为 'X' 的密钥已存在。将 'Overwrite' 设置为 true…"当 X 已在保险库中时调用 setSecret("X")要轮换/更新密钥,请调用 setSecret("X", Overwrite=true);否则请使用新名称
MATLAB:authnz:secretapis:SecretValueNotFound — "未找到密钥名称 'X' 对应的密钥值…"调用 getSecret("X"),但从未存储过 X(或名称拼写错误/大小写错误)先存储密钥(setSecret/importSecrets);读取前使用 isSecret("X") 检查。密钥名称区分大小写
MATLAB:authnz:secretapis:RemoveSecretFailed — "…未找到密钥名称 'X' 对应的密钥。"当 X 不在保险库中时调用 removeSecret("X")使用 if isSecret("X"); removeSecret("X"); end 检查

版权所有 2026 The MathWorks, Inc.


评论

支持 Markdown