Syncs active 1Password Business members into Snipe-IT as license seat assignments.
Reads all active (non-suspended) members from your 1Password SCIM Bridge and maps
each one to a seat on a named Snipe-IT software license. Seats are checked out when
a user becomes active and checked in when they are suspended or removed. The seat
notes field records the member's current 1Password role(s) (e.g. roles: Administrator).
Part of the *2snipe integration family, inspired by CampusTech's Snipe-IT integrations.
- 1Password Business account with SCIM Bridge deployed
- SCIM Bearer token from Admin Console → Integrations → SCIM Bridge
- Snipe-IT instance with API key (license management permissions)
Download a pre-built binary from the latest release:
# macOS (Apple Silicon)
curl -L https://github.com/jackvaughanjr/1password2snipe/releases/latest/download/1password2snipe-darwin-arm64 -o 1password2snipe
chmod +x 1password2snipe
# Linux (amd64)
curl -L https://github.com/jackvaughanjr/1password2snipe/releases/latest/download/1password2snipe-linux-amd64 -o 1password2snipe
chmod +x 1password2snipe
# Linux (arm64)
curl -L https://github.com/jackvaughanjr/1password2snipe/releases/latest/download/1password2snipe-linux-arm64 -o 1password2snipe
chmod +x 1password2snipe
Or build from source:
git clone https://github.com/jackvaughanjr/1password2snipe
cd 1password2snipe
go build -o 1password2snipe .
Copy settings.example.yaml to settings.yaml and fill in your values:
onepassword:
url: "https://your-scim-bridge.example.com"
api_token: "your-scim-bearer-token"
include_guests: false # set true to also sync Guest-role members
snipe_it:
url: "https://your-snipe-it-instance.example.com"
api_key: "your-snipe-it-api-key"
license_name: "1Password Business"
license_category_id: 5 # required — find at Admin → Categories
license_seats: 50 # optional — your purchased seat count (1Password has no API for this)All values can be set via environment variables instead:
| Variable | Config key |
|---|---|
OP_SCIM_URL |
onepassword.url |
OP_SCIM_TOKEN |
onepassword.api_token |
SNIPE_URL |
snipe_it.url |
SNIPE_TOKEN |
snipe_it.api_key |
SLACK_WEBHOOK |
slack.webhook_url |
Validate connections and report current state:
./1password2snipe test
Dry-run (simulate without making changes):
./1password2snipe sync --dry-run
Run a full sync:
./1password2snipe sync
Sync a single user:
./1password2snipe sync --email user@example.com
Create Snipe-IT accounts for unmatched users:
./1password2snipe sync --create-users
Include Guest-role members:
./1password2snipe sync --include-guests
| Flag | Description |
|---|---|
--config |
Path to config file (default: settings.yaml) |
-v, --verbose |
INFO-level logging |
-d, --debug |
DEBUG-level logging |
--log-file |
Append logs to a file |
--log-format |
text (default) or json |
- Fetches all active members from the 1Password SCIM Bridge (
active eq true) - Optionally filters out Guest-role members (default: excluded)
- Finds or creates the target license in Snipe-IT
- Expands the seat count if more active members than current seats
- Checks out a seat for each active member not yet assigned one
- Updates seat notes if the member's role has changed
- Checks in seats for members who are no longer active
1Password Business has five member types recorded in seat notes:
| Role | Description |
|---|---|
OWNER |
Account owner — full control |
ADMIN |
Administrator — can manage members and vaults |
MEMBER |
Standard member |
RECOVERY |
Recovery team member |
GUEST |
Guest — limited vault access (excluded by default) |
Set slack.webhook_url (or SLACK_WEBHOOK) to receive notifications on sync
completion, failures, and unmatched users. Suppressed in dry-run and with --no-slack.
A Dockerfile is included for containerized deployments. To build locally:
docker build -t 1password2snipe:latest .For automated scheduling via Cloud Run Jobs, use snipemgr — it handles image publishing, secret storage, and scheduling. See the snipemgr README for complete GCP setup instructions.
| Version | Key changes |
|---|---|
| v1.2.0 | Make Snipe-IT API rate limit configurable via sync.rate_limit_ms and SNIPE_RATE_LIMIT_MS env var |
| v1.1.0 | Added snipe_it.license_seats override for purchased seat count |
| v1.0.2 | Fixed ghost cleanup consuming all free seats on a newly created license |
| v1.0.1 | Fixed SCIM URL normalization; dropped unreliable server-side filter |
| v1.0.0 | Initial scaffold — 1Password SCIM → Snipe-IT license seat sync |