— 1PASSWORD OP STANDARD¶
Updated: 2026-08-29 Status: Binding operational companion to STD-AUTH-001
Canonical rules live in
Engineering-Standard/standards/core/authentication-secrets-constitution.md
(STD-AUTH-001). This file is command-wrapper guidance only. If they disagree,
the constitution wins.
Prime Directive¶
All secrets must enter processes only through 1Password CLI using approved wrappers. Never print, inspect, export, persist, commit, log, screenshot, or paste resolved secret values.
Secret Boundary Distinctions¶
DO_NOT_COMMIT: - raw API keys - .env files - rendered provider tokens - 1Password-resolved secret values - generated config containing credentials
ALLOWED_RUNTIME_USE:
- op run -- <command>
- environment variable injection into a local process
- DDEV/container process env
- CI masked variables
- temporary shell output during debugging, provided it is not copied into git, logs, screenshots, or tickets
Mandatory Git Guardrails¶
Any automated commit/push process must enforce these checks before staging/committing:
gitleaks protect --staged
git diff --cached --check
git diff --cached | grep -Ei "sk-[A-Za-z0-9]|OPENAI_API_KEY|ANTHROPIC_API_KEY" && exit 1 || true
Drupal Config Sync Boundary¶
For Drupal configuration (config/sync):
- Config may store provider selection, model name, offline banner state, and non-secret operational settings.
- Secrets must stay in:
- 1Password
- CI masked variables
- DDEV env
- Platform environment variables
- Secrets must not be exported through config/sync.
Approved Account¶
blueflyiollc
No Env Files¶
There is no canonical env file. .op-env and op run --env-file= are forbidden — an
env file is a second secret manifest and therefore a duplicate secret authority. Resolve
references directly (op read op://...), or open a process boundary with
op run --account blueflyiollc -- <command> when a command needs injected variables.
Canonical authority: BluCity-Docs Engineering-Standard/standards/core/authentication-secrets-constitution.md (STD-AUTH-001).
Allowed Secret Reference Format¶
op://Vault/Item/field
References belong in environment bindings, not in prompts, receipts, or agent context.
Do not assign resolved values. Do not create .op-env. Do not export long-lived credentials.
Execution Models¶
Model 1 — Workstation¶
Reuse the existing 1Password desktop session. Prefer Shell Plugin, then bounded op run -- <command>.
Do not eval "$(op signin)" as agent doctrine. Do not --env-file.
Model 2 — Oracle runtime¶
1Password Connect via the IaC op-connect env wrapper. Command substitution only. Never a file.
Do not copy workstation credentials onto Oracle.
Model 3 — Off-host CI¶
CI_JOB_TOKEN first. 1Password Service Account only when the operation cannot use native GitLab identity.
Recommended Runtime Assignment¶
workstation:
auth: 1Password desktop session + Shell Plugin / SSH Agent
use: operator-controlled commands
oracle_runtime:
auth: 1Password Connect (op-connect env)
use: long-lived Oracle services
ci_off_host:
auth: CI_JOB_TOKEN, then 1Password Service Account
use: GitLab SaaS/shared runners
forbidden:
- plaintext secrets in shell rc files
- .op-env / .env credential files
- copied PATs
- personal 1Password unlock shared across autonomous agents
- long-lived resolved env vars
Session credentials from manual CLI sign-in expire after inactivity. Oracle uses Connect. Agents do not stretch a personal interactive session.
Approved Command Wrappers¶
Git Push¶
op run --account blueflyiollc \
-- git push origin <branch-or-refspec>
GitLab CLI (preferred for interactive operator)¶
op plugin run -- glab <command>
GitLab CLI (agents / non-interactive)¶
Reuse an existing 1Password session or Service Account / Connect identity.
Inject the agent identity process-locally. Do not use macOS keyring as
credential authority (use_keyring: false on Bluefly glab hosts).
GITLAB_TOKEN="${GITLAB_AGENT_TOKEN_REF}" \
op run --account blueflyiollc -- glab <command>
GITLAB_AGENT_TOKEN_REF is bound at the environment/configuration layer to the
agent GitLab API credential in 1Password. Do not paste concrete op:// object
paths into prompts, Beads, receipts, or agent context (STD-AUTH-001 §11).
Identity roles (do not substitute randomly — STD-AUTH-001 §6):
| Role | Semantic ref | Consumer |
|---|---|---|
| Agent GitLab API | GITLAB_AGENT_TOKEN_REF |
glab / REST as @bluefly |
| Package registry | GITLAB_PACKAGE_REGISTRY_TOKEN_REF |
npm / Composer registry |
| CI | CI_JOB_TOKEN when sufficient |
GitLab CI jobs |
Rules (Token Truth — STD-AUTH-001 §5):
- Operator GitLab identity for Bluefly governance is
@bluefly, never@flux423. - Plain
glaboutside approved wrappers is forbidden. 401/optimeout / Touch ID / missing env = retrieval or credential-source failure — EXPIRATION_NOT_PROVEN.- Report
TOKEN_EXPIREDonly when calling GitLabGET /api/v4/personal_access_tokens/selfwith the exact intended token establishes that the token is expired or revoked. Example (process-local injection; never paste a PAT into the command line):
GITLAB_TOKEN="${GITLAB_AGENT_TOKEN_REF}" \
op run --account blueflyiollc -- glab api personal_access_tokens/self
Inspect active, revoked, and expires_at in the JSON. Do not use
curl with a pasted PRIVATE-TOKEN header.
GitLab CLI Fallback (operator)¶
GITLAB_TOKEN="${GITLAB_AGENT_TOKEN_REF}" \
op run --account blueflyiollc -- glab <command>
Composer¶
Shared CI owns Composer / package-registry authentication (gitlab_components).
Do not invent per-project token plumbing. Do not wrap Composer in .op-env.
DDEV (inside DDEV project root only)¶
op run --account blueflyiollc \
-- ddev <command>
Bluefly Git SSH Rule¶
All Bluefly Git remotes must use SSH.
Required remote shape:
git@gitlab-bluefly:blueflyio/<group>/<repo>.git
Preferred SSH: 1Password SSH Agent (existing SSH config). Do not copy private keys. Do not embed personal key paths in evergreen doctrine.
Never Use¶
- HTTPS Git remotes for Bluefly repos
- repo-local
.op-envassumptions - plaintext token files
- token echo/debug
- broad env dumps
- vault/item enumeration to discover secrets
- raw
op://placeholders in commands unlessop runorop injectresolves them glab auth loginglab auth refreshglab auth logout- plain
glaboutside approved wrappers curlwith pasted PAT- copied workstation secrets on servers
If op plugin glab Fails¶
- Treat as credential-source failure.
- Try only the approved
op runfallback. - If fallback also fails:
- Mark
AUTH_BLOCKED - Generate browser URL if possible
- Continue to next repo
- Do not try another auth path
Server / Runtime Rule¶
Laptop op is workstation-only.
CURRENT runtime secret retrieval is 1Password Connect, loaded on Oracle with op-connect env.
| Source | Classification |
|---|---|
| 1Password Connect | CURRENT — Oracle long-lived runtime |
| 1Password Service Account | CURRENT — CI off-host only (Connect is loopback) |
| Keycloak | Service identity, not a secret store |
HashiCorp Vault (templates/vault-auth) |
SUPERSEDED — do not add consumers |
Host .op-env / auth.env / EnvironmentFile= |
SUPERSEDED — do not recreate |
Do not copy workstation secrets to servers.
1Password Connect Mode (Oracle runtime)¶
Load Connect identity on Oracle with eval "$(op-connect env)" from the IaC wrapper.
Command substitution only. Never redirect to a file. Never paste the credential.
Heartbeat is reachability, not a second secret.
Authoritative deployment: blueflyio/agent-platform/infra/iac (oracle/onepassword-connect/, scripts/op-connect, deploy:onepassword-connect). Connect is loopback + docker-network only. CI does not reach it. Do not publish Connect on a routable interface.
SUPERSEDED dual-deploy: agent-docker deployments/oracle/services/onepassword-connect.yml mounting credentials JSON from disk. Do not stand up a second Connect. Consumers use the IaC endpoint.
Off-host GitLab CI uses CI_JOB_TOKEN, then a 1Password Service Account. That is a boundary Connect does not serve, not a fallback around an absent Connect.
1Password SDK — current status¶
blu-cli probes Connect first (connect), then service account, then desktop op whoami. The @1password/sdk desktop probe remains unimplemented — do not treat SDK retrieval as available.
Do not wrap every command in op run when Connect is the configured path.
Daemon / LaunchAgent Rule¶
Non-interactive runtimes must not depend on Desktop App biometric auth.
Use one of:
- Oracle runtime: 1Password Connect (op-connect env)
- CI off-host: OP_SERVICE_ACCOUNT_TOKEN
- Workstation interactive: existing 1Password session / Shell Plugin / SSH Agent
Forbidden:
- Background daemons waiting on biometric auth
- OP_AGENT_SOCK as a daemon auth workaround
- Committed generated env files with resolved values
- Personal operator identity for long-running services
Before daemonizing any service, run:
blu op daemon-check
Quick Rules (condensed reference)¶
Sourced from the concise
BLU-AUTHENTICATION.mdvariant for rapid lookup.
| Rule | Value |
|---|---|
| Account | blueflyiollc |
| Reference format | op://Vault/Item/field |
| Git remote shape | git@gitlab-bluefly:blueflyio/<group>/<repo>.git |
| SSH | 1Password SSH Agent (do not copy private keys) |
| Auth failure | Mark AUTH_BLOCKED, try fallback once, then skip |
| Server rule | Never copy workstation secrets to servers |
Operational signature¶
| Field | Value |
|---|---|
| Promoted by | Antigravity / DOCS Batch 007 |
| Source 1 | imports/BLU-AUTHENTICATION CONTROL PLANE.md |
| Source 2 | imports/BLU-AUTHENTICATION.md |
| Action | Merge (CONTROL PLANE base + Quick Rules appendix) |
| Sources retained | Yes |
| Delete performed | No |