GoingNinja Manual Knowledge Wiki logo
GoingNinja Manual Knowledge Wiki Lean MVP bootstrap documentation // Felix Rascher (WIP)

If you first need the beginner view of which accounts, domains, and provider access must exist before bootstrap can even start, read Before You Start.

If you need to prove that the machine can actually see the expected provider sessions and tokens, use the verification block below before assuming bootstrap is broken.

1. Why Resumable Bootstrap Needs A Credential Model

There is no serious “one-click” setup without a serious credential boundary.

The bootstrap script has to talk to real providers:

  • GitHub
  • Vercel
  • Neon
  • Cloudflare
  • review providers such as Anthropic and Google

The hosted wiki assistant adds one more provider class:

  • Mistral for the public wiki question-answer surface

If those credentials live only in ad-hoc environment variables, the system breaks as soon as the shell changes.

2. Scope Split

GoingNinja uses three layers:

Layer Holds Example
global provider scope reusable provider credentials CLOUDFLARE_API_TOKEN, VERCEL_TOKEN, NEON_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, MISTRAL_DEV_API_KEY, MISTRAL_PROD_API_KEY, gh session
project secret scope project-only secrets and URLs SESSION_SECRET, database URL, webhook secret, healthcheck URL
repo metadata non-secret record of what a project depends on .execution/credential-registry.json

Current service names:

  • global provider scope: rascher.global.providers
  • project scope: rascher.project.<slug>

These names follow the current single-operator namespace. A different operator replaces rascher with their own namespace; the platform does not require that literal prefix.1

3. Shell-Independent Loading

The current OS repo already ships a deterministic loader:

cd /path/to/goingninja-os
./scripts/load-global-providers.sh check
eval "$(./scripts/load-global-providers.sh exports)"
gh auth status

The key point is not the exact shell syntax. The key point is that the shell can be recreated from:

  • the repo
  • the registry
  • Keychain
  • provider CLI sessions

not from hidden shell history.

3a. How To Verify Provider Access Formally

Do not test provider readiness by printing secret values. Use formal status checks instead.

From goingninja-os, the normal check order is:

npm run access:check
./scripts/load-global-providers.sh check
eval "$(./scripts/load-global-providers.sh exports)"
gh auth status

What each step proves:

  • npm run access:check confirms that the required CLIs exist and that the required default provider entries are present.
  • ./scripts/load-global-providers.sh check confirms that each provider entry resolves to ready(...) or missing(...).
  • eval "$(./scripts/load-global-providers.sh exports)" confirms that the current shell receives the provider exports.
  • gh auth status confirms that the GitHub CLI session itself is alive.

Important boundary:

  • local shell exports are not the same as GitHub Actions secrets
  • GitHub Actions secrets are not the same as runtime app secrets

If one of those layers is missing, the machine may still fail even though another layer looks healthy.

4. What Lives In The Generated Repo

Each generated project repo contains a non-secret registry:

{
  "global_provider_service": "rascher.global.providers",
  "project_secret_scope": "<PROJECT_SLUG>",
  "entries": [
    { "name": "gh", "kind": "session", "status": "required" },
    { "name": "CLOUDFLARE_API_TOKEN", "kind": "global_keychain", "status": "optional" },
    { "name": "VERCEL_TOKEN", "kind": "global_keychain", "status": "optional" },
    { "name": "NEON_API_KEY", "kind": "global_keychain", "status": "optional" },
    { "name": "ANTHROPIC_API_KEY", "kind": "global_keychain", "status": "optional" },
    { "name": "GEMINI_API_KEY", "kind": "global_keychain", "status": "optional" },
    { "name": "MISTRAL_DEV_API_KEY", "kind": "global_keychain", "status": "optional" },
    { "name": "MISTRAL_PROD_API_KEY", "kind": "global_keychain", "status": "optional" }
  ]
}

This file exists so a new reader or a new shell can see what is needed without exposing the values.

For hosted assistants, the runtime variable may still be a neutral app-local name such as MISTRAL_API_KEY. The global provider scope keeps development and production keys separate so deploy targets can map the correct workspace key into that runtime variable without mixing environments.

5. Security Posture Today

What is true today:

  • secrets are not committed into generated repos
  • provider metadata is separated from provider values
  • the loader works without inheriting shell variables
  • the current local implementation is strong for a single macOS operator

Not yet true:

Boundary Current status
multi-user secret sharing not implemented
cloud-native secret vault abstraction not implemented
cross-platform secure storage not implemented; current path is macOS Keychain

Current threat-model statement:

  • this protects against committed-file leakage and most “new shell lost my env” failures
  • this does not protect against a compromised unlocked machine or local malware
  • this does not yet solve multi-user secret sharing or centralized rotation

6. Sources

Notes

  1. Implementation. scripts/load-global-providers.sh, .execution/credential-registry.json, and the Keychain service rascher.global.providers.