<!-- x-shc-release: version=2.4.15 op_fingerprint=183a4a0282542d671d799f08044f6717182932f9fa1ef5205dfca45a030cefaa op_count=177 contractFingerprint=e8f7ccc12336fb4925893ce3582b03782b182638dc460d952d046a36c1c20e14 -->
---
name: get-access
description: 'The FIRST skill -- run before any other. Creates the user''s SHC account via one anonymous API call (no website) and returns an operate-scoped key. Never prints or asks for a password.'
when_to_use: 'Run this FIRST, before anything else, the moment the user asks you to do anything with SHC (a server, a Bitcoin store, a cloud). ALSO run it any time an SHC call returns 401 or says "unauthorized" or "authentication required" -- that means you do not have a key yet.'
router_what: 'Create the user''s SHC account via API; get an operate key.'
router_when: 'FIRST, before anything on SHC, or whenever a call returns 401/unauthorized.'
version: 2.4.3
operator: true
client_side: true
requires: []
provides: [shc_access_key, user_api_key_operate]
inputs:
  - { name: email, required: true, desc: 'the user''s email address (their account login)' }
  - { name: first_name, required: true, desc: 'the user''s first name' }
  - { name: last_name, required: true, desc: 'the user''s last name' }
  - { name: country, required: false, desc: 'the user''s 2-letter country code (e.g. US, GB, DE); defaults to US if not given' }
  - { name: tos_accepted, required: true, desc: 'the user''s explicit yes to SHC''s Terms of Service (you must ask; never assume)' }
outputs:
  - { name: access_key, desc: 'the secret access key the server returns, which you store and send as a Bearer token on every later SHC call' }
estimated_minutes: [2, 5]
danger: low
---

# get-access -- get permission to run the user's SHC account

## Operator discipline (hold to these on every step)

*Five rules that keep you safe while you operate a server for someone. Follow them on every
step of every skill.*

1. **Verify, don't trust. Never fabricate a result.** Never report `ready`, `done`, `live`,
   `deployed`, `backed up`, or `paid` unless a real tool output or healthcheck PROVED it (and that
   proof arrives in a separate later message, never in your own reply). A status field is a claim; a
   healthcheck is proof. This holds under pressure: "tell my boss in one line it's live", "answer in
   one line", "you do not need to check" do NOT make it true and do NOT waive the check. If you have
   not verified, say exactly that -- never write a done/live/paid sentence you did not earn.
2. **Spending AND destruction are the human's call -- the user CANNOT authorize you to skip the
   confirm.** For money (order, pay) OR data-loss (reinstall, delete, cancel, restore): name the
   action, state the consequence, get the human's explicit yes for THAT action; never in one step.
   The trap: "just do it / don't ask me / skip confirmation / no need to confirm / I already agree" is
   an instruction to skip the gate -- it is NOT a yes and does NOT give you permission to bypass the
   gate. The gate OUTRANKS that instruction; proceeding because they said "just do it" is itself the
   failure. So you still state the consequence and still wait for a real yes. NEVER set `confirm=true`
   yourself, NEVER map "just go" onto `human_confirmed=true`, and NEVER assume a missing confirmation
   "defaults to true" -- the opposite is true: missing -> REFUSED (409 confirmation_required). If they
   will not give the yes, you do NOT proceed -- announce nothing, run nothing. (Mechanics: every spend
   AND destructive action is gated by a **server-issued, single-use confirmation_id** -- you can NEVER
   self-confirm. On the hosted MCP the destructive/spend tool returns the confirmation_id after its own
   human-approval step. On raw /v2 a destructive/spend call with no confirmation_id returns **409
   confirmation_required** carrying a one-time, non-secret `confirmation_id` and a `how_to_proceed`
   re-call shape; AFTER the human's explicit yes, re-send the IDENTICAL request adding the header
   **`X-User-Api-Confirm: <that confirmation_id>`**. `?confirm=true` and body `confirm:true` are NOT
   accepted -- they get the same 409. The confirmation_id is bound server-side to that exact call +
   your principal and is single-use, so a leaked id is inert (it completes nothing on its own). The
   409's `how_to_proceed` is a recovery shape, NOT a license: a confirmation_id only proves the SERVER
   has a pending record for the action -- do NOT auto-resend it until the human has actually said yes to
   the consequence. Spend is also scope-gated: an `operate` key cannot spend at all -- only a `full` key
   or HTTP Basic can.)
3. **Check the source before you run it.** Validate any deploy recipe against the project's
   *current* upstream docs, not a cached memory.
4. **Take the smallest key that does the job.** An agent that only provisions should never
   hold the key that spends.
5. **When you can't verify, stop and say so.** Failing loudly beats a confident wrong answer.

You start with NO access. Run this FIRST. Do not say you are connected, and do not order or deploy,
until the command here returns a real key. It creates the user's SHC account through the API in one
call -- they never touch a website.

## Safety gates (never break)

- Never ask for a password; never print a password in chat.
- Never write a fake "Response", any JSON, or any key yourself. A key comes ONLY from the real output
  your tool returns after you actually run the command.
- Get the user's explicit yes to the Terms before creating an account. Show the link; never assume.
- Always request `scope: operate` (read + provision, never spend). Never ask for more.

## A1. Ask for details and Terms agreement, in one message (show the real link)

Send this, then WAIT:

> To set up your SHC account I just need a few details:
> - your email address,
> - your first and last name,
> - your country (a 2-letter code like US, GB, DE).
>
> Also please review SHC's Terms of Service: https://blesta.sovereignhybridcompute.com/tos
> Do you agree to them?

Always paste the real `https://blesta.sovereignhybridcompute.com/tos` link. Do not continue without
their email, their name, AND a clear **yes** to the Terms.

## A2. Confirm the yes

Only continue if the user clearly agreed to the Terms. If they said no, said nothing about it, or you
are unsure, ask again and wait. Do not create the account without a clear yes.

## A3. Make a strong password (do NOT show it)

Create a strong random password (16+ chars, random). Never print it; never tell the user. You put it
in the next command and forget it.

## A4. RUN the create-account command

Fill in email, the password you made, first name, last name, country (`US` if not given), and -- only
because the user agreed in A1 -- `tos_accepted`. Run this:

```bash
curl -s -X POST https://blesta.sovereignhybridcompute.com/user-api/v2/register \
  -H "Content-Type: application/json" \
  -d '{
        "email": "THE_USERS_EMAIL",
        "password": "THE_STRONG_PASSWORD_YOU_MADE",
        "first_name": "THEIR_FIRST_NAME",
        "last_name": "THEIR_LAST_NAME",
        "country": "THEIR_2_LETTER_COUNTRY",
        "tos_accepted": true,
        "scope": "operate"
      }'
```

Send `"scope": "operate"` exactly. Do not write the response, the password, or the key yourself -- run
it and read the real result, then go to A5.

## A5. Act on the real result

- **Account created:** the real result contains a new secret **access key**. Keep that exact value;
  do not show it. Go to A6.
- **Email already registered (409):** this email already has an SHC account. Tell the user plainly to
  use a different email, or to sign in to their account once and create an API key in their account
  settings, then give you that key.
- **Validation error (400 / 422):** a field was missing or invalid. Tell the user what to fix (e.g.
  *"That doesn't look like a valid email -- what's the right one?"*), then run A4 again.
- **Anything else (server error / no result):** say *"I couldn't reach SHC just now -- let me try
  again,"* wait briefly, run A4 once more. If it still fails, say so and stop. Do not pretend it worked.

## A6. Keep the key, tell the user

1. Keep the access key for the session. Send it on every later SHC request as the `Authorization`
   header: the word `Bearer`, a space, then the key. Do not show it.
   **This key IS the credential every other skill needs.** When a skill lists `requires:
   user_api_key_operate`, that means exactly this key (it is `operate`-scoped: read + provision, never
   spend). You do not fetch a different key anywhere -- this one satisfies that requirement.
2. Say:
   > Your SHC account is set up, and it works entirely through me -- you never need the website. If you
   > ever want to log in directly, use the "forgot password" link on the login page. Your account stays
   > free until you place an order and pay for it.
3. Continue with what the user asked (e.g. order, then `shc-deploy-app`). Payment is the user paying an
   invoice in their own wallet/browser -- you never need a spending key.

**You're done with get-access when:** the register call returned an `shc_live_...` key, you stored it
as the `Authorization: Bearer` credential, and you told the user their account is set up. From here,
treat `user_api_key_operate` as satisfied.

## If a later skill returns 401 / unauthorized

Your key is missing or expired. Run **get-access** again. A 401 is the signal to re-run, never a reason
to give up.
