Point an app at a shared world
Run the app against the team's world and reach the vendor through it: no key in the app, every call in the log with its receipt, a check in the way.
This page supplies an executable walkthrough for packages/cli/src/journeys/tutorials.test.ts.
A shared world whose twin has a root is the vendor with its keys hidden. An app that talks to the world's URL instead of the vendor's is talking to the vendor: each write is performed the moment it arrives, the world answers with what the vendor minted, and every call is an entry in the world's log with its receipt. The credential is sealed beside the world and nowhere else. A check runs before any write is performed, and a refusal comes back in the vendor's error format.
Three worlds
GitHub itself is a world here, so the whole chain runs on one machine; the commands are the same
when the root is https://api.github.com.
{ "name": "acme-web", "private": true, "type": "module", "dependencies": { "@octokit/rest": "^21" } }The app declares the credential it reads. The World issues a throwaway token for its GitHub account,
world; that account is separate from the platform org acme. The seed creates world/web through
Octokit before any issue is written. It can run again without creating a second repository.
GITHUB_TOKEN=
GITHUB_API_URL=
VOLTER_WORLD_TOKEN=import { Octokit } from '@octokit/rest';
const github = new Octokit({ auth: process.env.GITHUB_TOKEN });
const { data: { login: owner } } = await github.users.getAuthenticated();
try {
await github.repos.get({ owner, repo: 'web' });
} catch (error) {
if (error.status !== 404) throw error;
await github.repos.createForAuthenticatedUser({ name: 'web' });
}// GitHub's own SDK: a throwaway GitHub token authenticates the account, and
// x-twins-key opens the served World. The app never receives the root's sealed credential.
import { Octokit } from '@octokit/rest';
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN, baseUrl: process.env.GITHUB_API_URL,
request: { headers: { 'x-twins-key': process.env.VOLTER_WORLD_TOKEN } },
});
try {
const { data: issue } = await octokit.issues.create({ owner: 'world', repo: 'web', title: process.argv[2] ?? 'Launch checklist' });
console.log(`filed #${issue.number}`);
} catch (error) {
console.log(`refused: ${error.message}`);
}import assert from 'node:assert/strict';
import { Octokit } from '@octokit/rest';
const github = new Octokit({ auth: process.env.GITHUB_TOKEN });
const { data: issues } = await github.issues.listForRepo({ owner: 'world', repo: 'web' });
assert.deepEqual(issues.map(issue => issue.title).sort(), ['Launch checklist', 'Something earlier']);
console.log('2 issues; refused title absent');GITHUB_TOKEN=import '../../acme-web/.volter/seed.ts';GITHUB_TOKEN=import '../../acme-web/.volter/seed.ts';import { readFileSync } from 'node:fs';
const worldToken = readFileSync('../reality/.volter/token', 'utf8').trim();
const response = await fetch('http://127.0.0.1:4400/acme/reality/github/_twin/app-credentials', {
method: 'POST', headers: { 'x-twins-key': worldToken, 'content-type': 'application/json' }, body: '{}',
});
if (!response.ok) throw new Error(`The local GitHub account did not issue a token (${response.status})`);
const { token } = await response.json();
if (!token) throw new Error('The local GitHub account returned no token');
console.log(process.argv.includes('--token') ? token : JSON.stringify({ headers: {
'x-twins-key': worldToken, authorization: `Bearer ${token}`,
} }));npm install
npm install -g @volter/world @volter/world-runtime
npm install -D @volter/twin-github
cd ../reality && volter world init --bare acme/reality --twins github
volter world up
volter world down
volter world serve --port 4400 &
cd ../team && volter world init --bare acme/team --twins github
volter world up
volter world down
volter world serve --port 4300 &
cd ../acme-web
for i in $(seq 1 60); do [ -f ../reality/.volter/token ] && [ -f ../team/.volter/token ] && break; sleep 1; done; sleep 3Wait for both serving announcements before continuing.
serving acme/reality http://127.0.0.1:4400/acme/reality
serving acme/team http://127.0.0.1:4300/acme/teamThe account already has an issue, so the numbers the vendor mints and the numbers a fresh twin would mint differ — and the page can show whose number the app gets.
cd ../reality
export ROOT_GITHUB_TOKEN=$(volter world run -- node ../acme-web/root-credential.mjs --token)
cd ../acme-web
curl -s -X POST http://127.0.0.1:4400/acme/reality/github/repos/world/web/issues -H "x-twins-key: $(cat ../reality/.volter/token)" -H "authorization: Bearer $ROOT_GITHUB_TOKEN" -H 'content-type: application/json' -d '{"title":"Something earlier"}' | grep -o '"number":[0-9]*'"number":1Set the root
On the shared world, tell the GitHub twin where the vendor is and seal the credential. deploy auto is what makes the world live: an entry is performed the moment it lands.
cd ../team
volter twin github root http://127.0.0.1:4400/acme/reality/github --scope repos/world/web --deploy auto
volter world run -- node ../acme-web/root-credential.mjs | volter twin github credential
volter twin github
cd ../acme-webgithub root http://127.0.0.1:4400/acme/reality/github/repos/world/web deploy auto credential sealedRun the app against the world
The app's environment names the World's URL and access token. Run it against that served World;
the command supplies its throwaway GitHub token, while the root's sealed credential stays on the server.
The number it gets back is the one the vendor minted — #2, not the #1 a twin on its own
would have said.
export GITHUB_API_URL=http://127.0.0.1:4300/acme/team/github VOLTER_WORLD_TOKEN=$(cat ../team/.volter/token)
volter-world attach http://127.0.0.1:4300/acme/team --token "$VOLTER_WORLD_TOKEN" -- node file-issue.mjsfiled #2Every call is in the world's log with its receipt: performed, and under which id at the vendor.
cd ../team
volter world log --receipts
cd ../acme-webgithub issue.opened issue:1 deployed 2Reality has it:
curl -s http://127.0.0.1:4400/acme/reality/github/repos/world/web/issues -H "x-twins-key: $(cat ../reality/.volter/token)" -H "authorization: Bearer $ROOT_GITHUB_TOKEN" | grep -o '"title":"[^"]*"'"title":"Launch checklist"The check that refuses, in the vendor's words
A check is a file under .volter/checks/ in the world that performs. The shipped one refuses any
entry carrying a credential-shaped string — before it is performed, and the app receives the check's
reason in GitHub's error format. (The twin numbers its next issue after the one the vendor minted, so
this one is #3 locally.)
volter-world attach http://127.0.0.1:4300/acme/team --token "$VOLTER_WORLD_TOKEN" -- node file-issue.mjs "Use sk-live-4e2c9a1b7f3d8e6a5c4b3a2f1e0d9c8b for now"
cd ../team
volter world log --receipts
cd ../acme-webrefused: a credential-shaped string in title - https://docs.github.com/rest
github issue.opened issue:3 refused no-secrets: a credential-shaped string in titleRead the account through its own World: the refused title never reached it.
volter-world attach http://127.0.0.1:4400/acme/reality --token "$(cat ../reality/.volter/token)" -- node verify-issues.mjs2 issues; refused title absentClean up
kill $(jobs -p)