• 请不要在回答技术问题时复制粘贴 AI 生成的内容
coolcoffee
V2EX  ›  程序员

Vibe Coding 时代,大家的 SSH 密钥凭证还躺在磁盘上吗?

  •  
  •   coolcoffee · 4h 27m ago · 2197 views

    有安全机构统计过,光 2026 年就至少有 687 个恶意包在 npm 、PyPI 等社区公开传播。比较知名的 TanStack 被投毒事件跟我擦肩而过——我那个项目要是晚两天创建就中招了。

    现在 AI 时代,大家用 Claude Code 、Codex 之类的工具基本都开着 --skip-permissions--yolo 模式。虽然后来 Claude Code 推出了 auto 模式,让 AI 来审批命令,安全性有了一点提升,但仍然无法从根源杜绝供应链攻击——总不可能让 AI 把每个包都审计一遍,那样用户的钱包可承受不起。

    目前已知的供应链攻击,基本都会想尽办法偷取本地的各种凭证:SSH 密钥、AWS Credentials 、npm login token 、Docker login token……SSH 密钥和 AWS 凭证一旦泄露,GitHub 代码和服务器就几乎在裸奔; npm 和 Docker 的 token 被盗,则会沦为供应链攻击下一跳的肉鸡。

    于是我开始琢磨怎么规避这种风险。后来看到 1Password 提供了一套方案:把 SSH 密钥、敏感环境变量等都托管在 1Password 里,需要用的时候在 macOS 上弹出指纹认证来授权。这样基本兼顾了安全和便利,唯一的小缺点就是推代码时人不在电脑前会认证失败🐶

    前置条件

    • 1Password8
    • 1Password CLI
    brew install --cask 1password-cli
    

    然后在 1Password 设置中开启 Developer 下的两个选项:Use the SSH AgentIntegrate with 1Password CLI

    SSH 密钥托管

    基本配置:GitHub

    编辑 ~/.ssh/config

    Host github.com
    	IdentityFile ~/.ssh/1p/github.com.pub
    	IdentitiesOnly yes
    	IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
    

    原理很简单:先在 1Password 里创建一个 SSH Key ,把公钥导出到 github.com.pub,然后在 config 里指定这个公钥文件。这样触发认证时,SSH Agent 就知道该用哪个私钥来签名。如果不指定 IdentityFile,在有多个 SSH Key 的情况下会逐个尝试,容易触发重试上限导致连接失败。

    进阶:Agent Forwarding

    但这里会有一个问题——假如我需要从 Mac 连接到一台 Linux 服务器,在远端需要 push 代码时,能不能让本地的 1Password 来完成认证?

    答案是可以的。关键配置是 ForwardAgent yes

    Host jenkins-ci
    	HostName 192.168.10.20
    	User ubuntu
    	IdentityFile ~/.ssh/1p/jenkins-ci.pub
    	IdentitiesOnly yes
    	ForwardAgent yes
    

    通过 ssh jenkins-ci 连上之后,如果在远端需要 git push 之类的操作,认证请求会沿着 SSH 通道转发回来,拉起本地 1Password 的指纹验证。

    如果不想要用 sshconfig 配置,也可以直接使用 ssh -A [email protected] 的方式。

    再进阶:两台 Mac 互连的场景

    还有一个更细的场景:假如两台 Mac 之间互相远程连接,提交代码时默认会拉起本地(发起连接的那台)的 1Password 认证。但如果我希望「本地操作就用本地 macOS 认证,被远程连接时就用远程 macOS 机器的认证」呢?

    答案是用 SSH config 的 Match 指令:

    Match host * exec "test -z $SSH_TTY"
    	IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
    

    $SSH_TTY` 只在通过 SSH 登录的会话中才有值,所以这条规则只在本地终端(非 SSH 会话)时才生效,这时使用本地 1Password 的 Agent Socket 。而当你是被远程连进来的,`$SSH_TTY 非空,这条规则跳过,认证就走远端自己的 1Password 。

    完整配置

    把上面的逻辑拼起来,最终的 ~/.ssh/config 长这样:

    Match host * exec "test -z $SSH_TTY"
    	IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
    
    Host github.com
    	# 指定个人密钥的公钥,避免在多身份环境下匹配到错误的 Key
    	IdentityFile ~/.ssh/1p/github.com.pub
    	IdentitiesOnly yes
    
    Host jenkins-ci
    	HostName 192.168.10.20
    	User ubuntu
    	IdentityFile ~/.ssh/1p/jenkins-ci.pub
    	IdentitiesOnly yes
    	ForwardAgent yes
    

    AWS 凭证托管

    AWS Credentials 同样是高危目标。平时 AWS CLI 在用,很多工具也会直接读 ~/.aws/credentials 文件,把密钥明文存在磁盘上总归不太舒服。

    可以用 1Password CLI 的 op read 来替代。做法是在 1Password 里新建一个登录项目,把账号的 label 改成 access key id,密码的 label 改成 secret access key,保存后在对应字段右侧找到「 Copy Secret Reference 」,拿到引用路径。

    最终配置成环境变量命令:

    export AWS_ACCESS_KEY_ID=$(op read "op://Private/AWS Access Key/access key id")
    export AWS_SECRET_ACCESS_KEY=$(op read "op://Private/AWS Access Key/secret access key")
    

    在有需要的时候执行,也可以设置成 alias 方便快速执行。

    执行后会弹出指纹验证,通过之后这两个环境变量就有值了。接下来正常使用即可:

    aws s3 ls
    

    或者打开其他依赖 AWS 配置的应用,比如用 OpenLens 管理 EKS:

    open -a /Applications/OpenLens.app
    

    延伸阅读

    1Password 官方文档写得更详细,涵盖了更多场景,推荐去看看:1Password 开发者文档

    对了,文档里提到的 Git Commit 签名功能——建议别开。不然 vibe coding 的时候有得受了,每次提交都要授权一次。折腾半天配好,也就是在 GitHub 的 commit 记录上多个 Verified 绿标,没啥实际意义。

    安全无绝对,同时安全和便利上是属于鱼和熊掌不可兼得。1password 是我大半年使用下来比较均衡的选项。

    各位如果有什么其他更好的方案,也欢迎互相讨论分享。

    33 replies    2026-07-22 15:41:43 +08:00
    lel020
        1
    lel020  
       4h 1m ago
    我有一些密钥迁移到 1password 上了,commit 签名我是一直有使用的,也一起迁移到 1password 了,每次 commit 都要授权,使用起来真的很不方便,偶尔的 bug 就不说了, 电脑锁屏时没有任何办法授权使用密钥,远程 agent 就坑到了,
    mangoDB
        2
    mangoDB  
       3h 45m ago
    感谢科普好文,已经用了 5 年的 1Password 了,特别喜欢这个 SSH 集成功能。
    CyJaySong
        3
    CyJaySong  
       3h 40m ago
    私钥设置个密码也好嘛
    SmithJohn
        4
    SmithJohn  
       3h 35m ago
    不要用软件做隔离,用虚拟机做隔离.
    不希望让 AI 读取的密钥就不要让他存在于安装了 AI 的机器里.
    NASK
        5
    NASK  
       3h 22m ago
    我用的开源的 bitwarden,也支持 ssh-agent,可以解决密钥不放到~/.ssh 文件夹的问题 https://bitwarden.com/help/ssh-agent/
    更多的时候,我用的免费版的 termius 来管理服务器,用 bitwarden 来存储私钥,需要什么私钥就复制一份到 termius
    my3157
        6
    my3157  
       3h 13m ago via Android
    用 remote ssh 或者 dev container ,把 agent 放到一个干净隔离的环境,最多泄露 llm key
    Andrue
        7
    Andrue  
       3h 12m ago
    bitwarden+1
    coolcoffee
        8
    coolcoffee  
    OP
       2h 55m ago
    @lel020 所以我实践下来就是不要开 commit 签名,弹窗太多了也是一种负担,特别是现在 ai 喜欢一个功能十几次 commit ,还每次确认不就是回到了以前的 accept reject 模式吗?


    @CyJaySong 设置密码是增加了安全。但是远程 ssh 经常性的需要重连,每次输入密码不会觉得很繁琐吗?而且密码如果太简单和没设置的效果是差不多的。


    @SmithJohn @my3157 大部分的 web 前后端都是可以放在虚拟机甚至容器里面完成这个没问题,但是像 iOS 软件开发要追求运行效率,不太可能再嵌套一层虚拟机或者花银子再买一台新设备。
    coolcoffee
        9
    coolcoffee  
    OP
       2h 50m ago
    @NASK 感谢分享! 看来 bitwarden 也实现了和 1password 一样的功能,如果愿意折腾自建的话也能实现功能平替。
    yinmin
        10
    yinmin  
       2h 40m ago via iPhone
    ssh key 可以改扩展名加密码放在其它目录,使用命令 ssh-add 把 key 加入到 agent 就不用每次登录输入密码了。
    SmithJohn
        11
    SmithJohn  
       2h 36m ago
    @coolcoffee macos 没有 docker/podman?
    zengxs
        12
    zengxs  
       2h 35m ago
    1password 太贵了,我选择让 ai 自己写了个 ssh agent ,密钥放 iCloud keychain 里

    ysc3839
        13
    ysc3839  
       2h 34m ago via Android
    已经改成 KeePass 和 Yubikey 了
    keyu1103
        14
    keyu1103  
       2h 31m ago
    1password 的 ssh agent ,实测会有些问题。
    比如 codex 调用的时候,子进程的请求会被 1p 识别为后台申请,被静默到标题栏图标里
    coolcoffee
        15
    coolcoffee  
    OP
       2h 31m ago
    @yinmin ssh agent 不仅仅起到密码免输入作用,还有关键的生物指纹方式来快速二次认证。不然恶意程序可以服务器记录认证一遍把其他密钥加进去。


    @SmithJohn 我已经限定了是 web 前后端用容器完全没问题, 我自己就经常是 macOS 远程连接 Linux server 来开发。 得益于 ssh forward agent 特性,我远程服务器都可以不用配置 git 或者其他服务器的密钥,需要的时候会自动唤醒 macOS 本地的 1password 来授权。
    coolcoffee
        16
    coolcoffee  
    OP
       2h 26m ago
    @zengxs 哈哈,这个可以的。再加个类似 1password cli 的 op get 的方式就可以作为一个独立软件使用了,iCloud keychain 是同时满足跨设备便利和安全中比较不错的选择。


    @keyu1103 我使用 claude code 大部分时候都能正常唤醒,没见过有标题栏图标提示,所以我这边后面也补充了 commit 不要去开验证,至少先让 ai 把功能写完🤣
    coolcoffee
        17
    coolcoffee  
    OP
       2h 23m ago
    @ysc3839 Yubikey 我也有考虑过。虽然硬件保证了物理上的安全,但是同时引入了物理损坏和丢失的风险。看每个人对于安全和便利之间不同的取舍了。
    gorvey
        18
    gorvey  
       2h 22m ago
    我用的 bitwarden ssh agent ,只是为了同步方便,没有开验证,静默确认
    zengxs
        19
    zengxs  
       2h 20m ago   ❤️ 1
    @coolcoffee 一开始是想用 ai 做个 bitwarden 的 native 客户端( bitwarden 那个客户端有点难用,而且资源开销也大),后来评估了一下,感觉工作量太大,退而求其次只做了 ssh agent

    现在最基本功能是 ok 的,不过作为一个独立软件 其实细节上还差很多打磨,还有签名审计这些功能都还没做

    源码在这 https://github.com/zengxs/Gizmoire
    GeruzoniAnsasu
        20
    GeruzoniAnsasu  
       1h 59m ago
    有个几十年(?)历史的经典解决方案:gpg-agent

    ssh 密钥从 gpg 派生,一样不落盘
    runliuv
        21
    runliuv  
       1h 53m ago
    不用 SSH ,写代码只用 GIT,SVN.
    deepbytes
        22
    deepbytes  
       1h 48m ago via iPhone
    Yubikey 解决问题
    SHIINASAMA
        23
    SHIINASAMA  
       1h 42m ago
    @zengxs #12 这个好诶,可以分享一下吗
    cutiechi
        24
    cutiechi  
       1h 39m ago
    bitwarden ssh agent 好像有个问题,就是没办法拿到实际的程序是什么
    zengxs
        25
    zengxs  
       1h 20m ago
    @SHIINASAMA 代码仓库在上面贴了
    DejavuMoe
        26
    DejavuMoe  
       1h 13m ago
    一直用 Yubikey OpenPGP SSH
    Rehtt
        27
    Rehtt  
       47 mins ago
    在 macOS 用的 Secretive ,密钥是在电脑硬件安全区,私钥是导不出来的,可以看作是 Yubikey 替代版
    coolcoffee
        28
    coolcoffee  
    OP
       47 mins ago
    @runliuv Git 不也是需要 ssh 密钥来认证吗? 当然你要是用密码就当没说。


    @GeruzoniAnsasu 单机守护对于 macOS 很简单,M 芯片支持 Secure Enclave 硬件加密同样支持不会落盘,但是同时也失去了跨平台同步的特性。


    @zengxs 软件还不错,如果有开发者证书的话打包公证出一个 dmg 包来下载。
    ysc3839
        29
    ysc3839  
       46 mins ago via Android
    @coolcoffee 可以加多几个密钥
    fengci
        30
    fengci  
       41 mins ago
    @Rehtt 那 agent 读取密钥的时候 都需要确认? 如果是远程 coding 怎么办?
    coolcoffee
        31
    coolcoffee  
    OP
       38 mins ago
    @ysc3839 这个可以有。为了这个物理安全的灾备也只能苦一苦钱包了🤣
    yapingchen00
        32
    yapingchen00  
       37 mins ago
    @fengci 远程 coding 应该按需在远程机器上提供吧。
    coolcoffee
        33
    coolcoffee  
    OP
       35 mins ago
    @fengci 你可以研究一下 Secretive 是否能支持类似 1password 的 Forward Agent 特性,理论上也是可以支持。万一不行还可以直接拿 github 仓库去改改。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5379 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 109ms · UTC 08:16 · PVG 16:16 · LAX 01:16 · JFK 04:16
    ♥ Do have faith in what you're doing.