As organizations grow, so does the complexity of managing software licenses and user access. I recently discovered that our 1Password Business account had several users consuming licenses who weren't actually accessing any vaults or assigned to meaningful groups beyond the default "team members" group. This meant we were paying for licenses that provided no real value to those users.
The Problem: Phantom License Usage
When I audited our 1Password organization, I found users who were:
- Only assigned to the basic "team members" group
- Had no direct vault access permissions
- Weren't members of any functional groups with specific vault access
These users were essentially consuming licenses without being able to access any company passwords or secrets. They were taking up seats in our license pool but couldn't actually use 1Password for its intended purpose.
You can see below, we have 4 people that have a license but have no access to company vaults.
Shell Script Audit of Users
Using the 1Password CLI, I created a simple audit script to identify these users. The approach breaks down into a few key steps:
Step 1: Gather All Users and Groups
# Get all users in JSON format
op user list --format=json > users.json
# Get all groups
op group list --format=json > groups.json
# Get all vaults
op vault list --format=json > vaults.json
Step 2: Check Group Memberships
For each user, I check which groups they belong to:
# For each user, check their group memberships
for user_id in $(jq -r '.[].id' users.json); do
echo "Checking user: $(jq -r ".[] | select(.id==\"$user_id\") | .name" users.json)"
# Check each group for this user
for group_id in $(jq -r '.[].id' groups.json); do
op group user list $group_id --format=json | jq -r ".[] | select(.id==\"$user_id\") | .id" 2>/dev/null
done
done
Step 3: Check Direct Vault Access
I also need to verify they don't have direct vault permissions:
# For each vault, check if user has direct access
for vault_id in $(jq -r '.[].id' vaults.json); do
op vault user list $vault_id --format=json 2>/dev/null | jq -r ".[] | select(.id==\"$user_id\") | .id"
done
Step 4: Identify License Waste
The complete audit script identifies users who:
- Are only in "team members" (or no groups)
- Have no direct vault assignments
- Are consuming a license unnecessarily
#!/bin/bash
# 1Password License Audit Script
echo "Starting 1Password license audit..."
# Ensure we're signed in
if ! op account get >/dev/null 2>&1; then
echo "Please sign in to 1Password CLI first: op signin"
exit 1
fi
# Get data
echo "Fetching users, groups, and vaults..."
op user list --format=json > /tmp/users.json
op group list --format=json > /tmp/groups.json
op vault list --format=json > /tmp/vaults.json
echo "Analyzing user access..."
users_without_access=()
while IFS= read -r user; do
user_id=$(echo "$user" | jq -r '.id')
user_name=$(echo "$user" | jq -r '.name')
user_email=$(echo "$user" | jq -r '.email')
echo "Checking: $user_name"
# Check group memberships (excluding "team members")
other_groups=0
while IFS= read -r group; do
group_id=$(echo "$group" | jq -r '.id')
group_name=$(echo "$group" | jq -r '.name')
if [ "$group_name" != "team members" ]; then
if op group user list "$group_id" --format=json 2>/dev/null | jq -e ".[] | select(.id==\"$user_id\")" >/dev/null; then
other_groups=$((other_groups + 1))
fi
fi
done < <(jq -c '.[]' /tmp/groups.json)
# Check direct vault access
direct_vaults=0
while IFS= read -r vault; do
vault_id=$(echo "$vault" | jq -r '.id')
if op vault user list "$vault_id" --format=json 2>/dev/null | jq -e ".[] | select(.id==\"$user_id\")" >/dev/null; then
direct_vaults=$((direct_vaults + 1))
fi
done < <(jq -c '.[]' /tmp/vaults.json)
# If no other groups and no direct vault access
if [ $other_groups -eq 0 ] && [ $direct_vaults -eq 0 ]; then
users_without_access+=("$user_name ($user_email)")
echo " → No meaningful access found"
else
echo " → Has access ($other_groups groups, $direct_vaults direct vaults)"
fi
done < <(jq -c '.[]' /tmp/users.json)
# Report results
echo ""
echo "=== AUDIT RESULTS ==="
echo "Users consuming licenses without vault access:"
echo ""
if [ ${#users_without_access[@]} -eq 0 ]; then
echo "✅ No users found without meaningful access"
else
printf '%s\n' "${users_without_access[@]}"
echo ""
echo "Found ${#users_without_access[@]} users who may not need 1Password licenses"
fi
# Cleanup
rm -f /tmp/users.json /tmp/groups.json /tmp/vaults.json
Taking Action
Once I identified these users, I had a few options:
- Remove them entirely - no point using a license for no reason, they are not free
- Add them to appropriate groups - after a quick e-mail to the user.
The key insight is that simply being in the "team members" group doesn't provide access to anything useful - it's essentially a placeholder that consumes a license slot.
Conclusion
A simple shell script audit saved us hundreds of dollars annually and helped optimize our 1Password deployment. If you're managing a 1Password Business account, I highly recommend running a similar audit to identify license waste in your organization.