Skip to content

Migrate Connect to use Connect SDK instead of CLI#138

Closed
JillRegan wants to merge 29 commits intomainfrom
jill/migrate-to-connect-sdk
Closed

Migrate Connect to use Connect SDK instead of CLI#138
JillRegan wants to merge 29 commits intomainfrom
jill/migrate-to-connect-sdk

Conversation

@JillRegan
Copy link
Copy Markdown
Contributor

@JillRegan JillRegan commented Feb 20, 2026

Overview

This PR updates the Connect-based secret resolution path to use the 1Password Connect JavaScript SDK when OP_CONNECT_HOST and OP_CONNECT_TOKEN are provided, instead of shelling out to the op CLI. The goal is to keep behavior consistent with the current action while making Connect resolution fully SDK-driven.

When users configure the action for Connect (OP_CONNECT_HOST + OP_CONNECT_TOKEN), we must resolve op:// references via the Connect API. The op CLI’s Go implementation is used as the reference spec for:

  • parsing secret refs in the form op://vault/item/section/field
  • resolving items/fields/sections correctly
  • matching fields/sections in a way consistent with current CLI behaviour
  • Validate secret references, ensuring Connect usage matches the validation rules used for service accounts.

What Changed

  • Replaced CLI with Connect SDK JS calls.
  • Implemented op:// reference parsing and resolution compatible with the CLI Go behavior
  • vault, item, optional section, and field are handled
  • correct matching logic for fields and sections
  • Added/updated tests to cover Connect SDK resolution and validation behavior

How to Test Manually

I tested this locally by:

  1. Checking out this branch and ensure Docker is running
npm install
npm run build
export OP_CONNECT_CREDENTIALS="$(cat /path/to/1password-credentials.json)"
export OP_CONNECT_TOKEN="your-token"
export VAULT="Your Vault Name"

  1. Create workflow file: .github/workflows/test-locally.yml and added the below script. FYI as long as Docker is runnign this will spin up a connect server for you do you don't have to do it yourself.

The item and field names in the workflow (e.g. test-secret, file-secret, multiline-secret) match the current testing vault used for this action. You can change them to match your own vault, items, and fields.

name: Local Connect E2E Test

on:
  workflow_dispatch:

jobs:
  test-connect:
    name: Connect (local)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Build actions
        run: npm run build:all

      - name: Generate .env.tpl
        run: |
          mkdir -p tests
          echo "FILE_SECRET=op://${{ secrets.VAULT }}/test-secret/password" > tests/.env.tpl
          echo "FILE_SECRET_IN_SECTION=op://${{ secrets.VAULT }}/test-secret/test-section/password" >> tests/.env.tpl
          echo "FILE_MULTILINE_SECRET=op://${{ secrets.VAULT }}/multiline-secret/notesPlain" >> tests/.env.tpl
          echo "FILE_SECRET=op://${{ secrets.VAULT }}/file-secret/test.txt" >> tests/.env.tpl
          echo "SECRET_WITH_FILE_IN_SECTION=op://${{ secrets.VAULT }}/file-secret/test-section/test.txt" >> tests/.env.tpl
          echo "SECRET_WITH_FILE=op://${{ secrets.VAULT }}/file-secret/file section/test.txt" >> tests/.env.tpl
          echo "DOUBLE_SECTION_SECRET=op://${{ secrets.VAULT }}/double-section-secret/test-section/password" >> tests/.env.tpl

      - name: Launch 1Password Connect instance
        env:
          OP_CONNECT_CREDENTIALS: ${{ secrets.OP_CONNECT_CREDENTIALS }}
        run: |
          echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
          docker compose -f tests/fixtures/docker-compose.yml up -d && sleep 10

      - name: Configure 1Password Connect
        uses: ./configure
        with:
          connect-host: http://localhost:8080
          connect-token: ${{ secrets.OP_CONNECT_TOKEN }}

      - name: Load secrets
        id: load_secrets
        uses: ./
        with:
          version: latest
          export-env: true
        env:
          SECRET: op://${{ secrets.VAULT }}/test-secret/password
          SECRET_IN_SECTION: op://${{ secrets.VAULT }}/test-secret/test-section/password
          MULTILINE_SECRET: op://${{ secrets.VAULT }}/multiline-secret/notesPlain
          SECRET_WITH_FILE: op://${{ secrets.VAULT }}/file-secret/test.txt
          SECRET_WITH_FILE_IN_SECTION: op://${{ secrets.VAULT }}/file-secret/file section/test.txt
          DOUBLE_SECTION_SECRET: op://${{ secrets.VAULT }}/double-section-secret/test-section/password
          OP_ENV_FILE: ./tests/.env.tpl

      - name: Assert test secret values
        run: ./tests/assert-env-set.sh

      - name: Assert file secret (test.txt)
        run: |
          if ! printenv SECRET_WITH_FILE | grep -qF 'This is a test'; then
            echo "SECRET_WITH_FILE missing expected content from test.txt"
            exit 1
          fi
          if ! printenv SECRET_WITH_FILE_IN_SECTION | grep -qF 'This is a test'; then
            echo "SECRET_WITH_FILE_IN_SECTION missing expected content from test.txt"
            exit 1
          fi
  1. run brew install act
  2. Run the workflow with act (ensure OP_CONNECT_CREDENTIALS, OP_CONNECT_TOKEN, and VAULT are set or passed):
   act workflow_dispatch -W .github/workflows/test-locally.yml -j test-connect \
     -s OP_CONNECT_CREDENTIALS \
     -s OP_CONNECT_TOKEN \
     -s VAULT

run: |
echo "$OP_CONNECT_CREDENTIALS" > 1password-credentials.json
docker compose -f tests/fixtures/docker-compose.yml up -d && sleep 10
docker compose -f tests/fixtures/docker-compose.yml up -d && sleep 30
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

increased start up time now that we are testing for file content

Comment thread src/utils.ts
}

if (fileId) {
return getFileContentWithRetry(client, parsed.vault, parsed.item, fileId);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran into issues with getting file content returning 503. This was only happened in e2e runs on GitHub Actions and could not be reproduced locally. The server may be temporarily overloaded or unavailable. Loading file content is now retried on 503 (up to 3 attempts with a 2s delay) so transient failures in CI don’t cause the action to fail.

Base automatically changed from jill/validate-secret-reference to feature/migrate-to-sdk February 23, 2026 16:42
@JillRegan JillRegan marked this pull request as draft February 26, 2026 17:50
Base automatically changed from feature/migrate-to-sdk to main February 27, 2026 19:13
@JillRegan JillRegan closed this Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant