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

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

  •  1
     
  •   coolcoffee · 1 day ago · 4770 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 是我大半年使用下来比较均衡的选项。

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

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


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


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

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


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


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

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

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

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


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


    @zengxs 软件还不错,如果有开发者证书的话打包公证出一个 dmg 包来下载。
    ysc3839
        29
    ysc3839  
       1 day ago via Android
    @coolcoffee 可以加多几个密钥
    fengci
        30
    fengci  
       1 day ago
    @Rehtt 那 agent 读取密钥的时候 都需要确认? 如果是远程 coding 怎么办?
    coolcoffee
        31
    coolcoffee  
    OP
       1 day ago
    @ysc3839 这个可以有。为了这个物理安全的灾备也只能苦一苦钱包了🤣
    yapingchen00
        32
    yapingchen00  
       1 day ago
    @fengci 远程 coding 应该按需在远程机器上提供吧。
    coolcoffee
        33
    coolcoffee  
    OP
       1 day ago
    @fengci 你可以研究一下 Secretive 是否能支持类似 1password 的 Forward Agent 特性,理论上也是可以支持。万一不行还可以直接拿 github 仓库去改改。
    Leeeeex
        34
    Leeeeex  
    PRO
       23h 29m ago
    可以 只给 tag 开验证,之后最终一步签个名。
    楼上说的 yubikey 太麻烦了,走哪带哪,我还是习惯用 1password 的 passkey 。
    zengxs
        35
    zengxs  
       22h 29m ago   ❤️ 1
    yulgang
        36
    yulgang  
       22h 19m ago
    agent 丢在 wsl2(不挂载 Windows 分区)或者虚拟机里了
    ryd994
        37
    ryd994  
       16h 41m ago via Android
    @coolcoffee #17
    1. ssh key 可以不止一个,yubikey 也可以不止一个
    2. 1password 的安全性本身也是一种风险
    3. 企业用或者比较正式的情况都是不用 ssh authorized_keys 的。而是用 CA 签名,同样也能通过 CA revoke 。更正式一点的会用跳板机,
    ryd994
        38
    ryd994  
       16h 39m ago via Android
    @coolcoffee #28 git 可以用 token 啊。给哪个 repo 给多少权限都可以控制。
    ryd994
        39
    ryd994  
       16h 35m ago via Android
    @coolcoffee #17 补充一下,常用机器配 yubikey 可以不用随身带的。USBC nano 嵌在电脑里,不影响美观。
    这样做不影响安全,因为 yubikey 还是有个短 pin 锁住,可以配置失败锁死。只要你设置的 pin 不要前 N 次被人猜到,你的密钥就是安全的。
    shmilypeter
        40
    shmilypeter  
       16h 8m ago
    @ryd994 说到 yubikey ,我曾想过这样的需求场景。

    我的 Mac 需要 yubikey 插上+指纹鉴权+密码三样全部通过才可以解锁。敏感操作可以按 yubikey 上的按键二次确认,比如调用系统的 keychain 和 passkey 或者 ssh 之类。

    yubikey 需要足够坚固,但也要有一键自毁措施。比如可以设置按键长按 3 秒+连续短按 3 次直接失效。

    但这样的需求问了 AI 无法实现,插上 yubikey 之后一般只能选 yubikey+密码,会接管系统的指纹选项。yubikey 也没有自毁措施。
    shmilypeter
        41
    shmilypeter  
       16h 3m ago
    @ryd994 对,一般企业 MDM 的机器都会绑定基于你工号签发的 CA ,你的 teams 只能在你的 Mac 上登录。
    nrtEBH
        42
    nrtEBH  
       5h 8m ago
    密钥都有轮换机制 重要的账户都有 MFA 本地 key 丢失不是什么很严重的问题
    另外 我从不开 yolo 之类的
    比起 sshkey 泄露 rm -rf / 才是最害怕的
    seenthewind
        43
    seenthewind  
       4h 41m ago
    sshkey 既然给大模型了,早晚会泄漏的,根本的原因是 key 不再单纯的用来直接开门,而是给管家了。。。
    coolcoffee
        44
    coolcoffee  
    OP
       4h 39m ago
    @ryd994 我后面研究一下 1password 使用 yubikey 能结合到什么程度。

    github token 对于仓库和设备也比较多就比较麻烦。在 macOS 和 Windows 还有系统区域可以保护,在 Linux 中同样是明文形式存储可以被拖走。
    coolcoffee
        45
    coolcoffee  
    OP
       4h 29m ago
    @nrtEBH 担心数据丢失的风险可以用 macOS time machine ,插上硬盘无感备份。终端只要不开全盘访问,被删光的风险相对比较小。
    不过我现在都尽可能的把数据都放 dropbox 、icloud 、onedrive ,以及代码都放 github ,尝试过几次完全格式化再重装都无感。


    @seenthewind sshkey 为什么需要给大模型呢?这块就是要拦着不随便给。不然我看到 Twitter 不知道是不是段子,说需要某个功能需要用 GPU 加速,结果 AI 拿着阿里云的凭据直接去开 GPU 机器了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5348 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 121ms · UTC 07:48 · PVG 15:48 · LAX 00:48 · JFK 03:48
    ♥ Do have faith in what you're doing.