Tutorial: your first gated operation¶
Publish a disposable secret to a test GitHub repository, approve the request, and inspect the broker's audit record. The operation returns status without returning the secret value through Opaque.
This is a local learning exercise: agent and daemon share your user account. It does not isolate credentials from other processes with that account's access. Use a throwaway value and test repository, not production credentials or data.
Steps 1–4 need macOS or a Linux graphical desktop with native approval configured. Step 5 also needs access to a test repository and a disposable GitHub token authorized to manage its Actions secrets.
What you are about to build¶
The broker checks policy, requests approval, resolves a credential reference, and calls GitHub. The CLI exercises the same broker before you connect an agent.
1. Install¶
This tutorial covers the baseline broker flow. The reviewer app, signed MCP v2 projections and portable checkpoints ship in the v0.6.0 release archives, and the scoped authority workflow is available from v0.6.0; see getting started for the package contents and build paths. Before upgrading an existing installation, follow the audit migration guide.
Check the installed version and binary paths:
2. Start from a policy you can read¶
For a fresh installation:
Open ~/.opaque/config.toml. If a configuration already exists, review it instead
of overwriting it. These instructions assume the unchanged github-secrets preset.
Its Actions-secret rule is:
[[rules]]
name = "allow-github-actions-secret"
operation_pattern = "github.set_actions_secret"
allow = true
client_types = ["agent", "human"]
[rules.approval]
require = "always"
factors = ["local_bio"]
The preset also permits other GitHub secret operations, including deletion;
it is not restricted to your test repository. Writes and deletions require
approval each time. Listing and test.noop use first-use approval with a
five-minute lease. Unmatched operations are denied. For narrower repository
and secret-name rules, see policy.
3. Run the daemon¶
In a second terminal, start the broker and leave it running:
Back in the first terminal:
A successful ping confirms connectivity. Read startup errors before proceeding; ordinary session-mode startup does not establish separate credential custody.
4. Run your first gated operation¶
Review the operation in the native prompt, then approve using the configured native authentication. Linux requires an intent dialog followed by polkit. If review cannot open, fix that prerequisite before continuing.
A successful no-op checks the local request and approval path without contacting a provider. Repeating the same request within its valid lease can skip another approval. That lease does not apply to the GitHub write below.
5. Give the daemon your secrets¶
Store two values interactively: the disposable GitHub token and a throwaway
value. These commands match the resolver's keychain:service/account format.
Do not put values in command arguments or agent messages.
Enter the token at the first prompt and the throwaway value at the second.
The references are keychain:opaque/github-pat and
keychain:opaque/tutorial-value. An existing entry may need separate review;
do not replace credentials belonging to another installation.
6. Publish the disposable secret¶
Replace the repository placeholder with your test repository. This creates or
replaces its TUTORIAL_KEY Actions secret:
opaque github set-secret \
--repo YOUR_ORG/YOUR_REPO \
--secret-name TUTORIAL_KEY \
--value-ref keychain:opaque/tutorial-value
Confirm the repository and secret name in the approval prompt. Success means GitHub accepted the write; it does not establish what a workflow later did with the value. Opaque's response omits the value. A process with independent keychain access or control of a consuming workflow has a different access path.
With the unchanged preset, this GitLab operation should be denied before provider execution:
opaque gitlab set-ci-variable \
--project tutorial/denied \
--key TUTORIAL_KEY \
--value-ref keychain:opaque/tutorial-value
Expect policy_denied; no GitLab token is needed. If your result differs,
inspect the active policy before proceeding.
7. Read the audit trail¶
Inspect recorded operation, approval, provider and denial events. Increase
--limit if the relevant events are outside the displayed window. Results and
event counts depend on your run; a provider error is not a successful write.
Verification checks local audit integrity under its custody assumptions. Someone holding the audit HMAC key can forge records; verification cannot establish that a compromised broker reported truthfully. Whole-state rollback also needs an independently retained reference to detect. See signed evidence checkpoints for authenticated heads, retained references and verification limits.
8. Point your agent at it¶
For Claude Code, Cursor or Codex, let the CLI write the entry:
For any other MCP client using an mcpServers configuration, add:
Use the path from command -v opaque-mcp and your client's supported configuration
location. Restart or reconnect the client, then confirm it lists
opaque_github_set_actions_secret. See MCP integration.
Ask it to set TUTORIAL_KEY in your test repository using
keychain:opaque/tutorial-value. Review the resulting request before approval.
This built-in tool returns operation status without exposing the secret value
through its result. It does not restrict the agent's independent tools or account.
Review your results¶
Check your own outcomes: no-op completed, GitHub accepted the write, GitLab was denied, and audit verification passed. Record failures as failures. This exercise is not a production security assessment or evidence of customer deployment.
Afterward, remove the test secret through GitHub and revoke the disposable token.
Where to go next¶
- Deployment: separate broker custody and its trust assumptions.
- Bounded agent work: exact task manifests, durable consumption and outcome receipts beyond this single-operation flow.
- Identity and policy: attributed access and narrower rules.
Troubleshooting¶
Daemon unreachable: inspect the foreground broker's startup error.
Linux prompt missing: check the graphical session, dialog helper and polkit setup in Linux native approvals.
Unsealed configuration: review deployment before sealing. A seal does not protect against someone who can replace its key.
Unexpected denial: inspect opaque policy show and opaque audit tail.