Skip to content

Accounts and security

Gigahost accounts do not use an email address, a conventional username, or a password you choose. Your account is controlled by a random 256-bit account key, kept as a seed file, account.seed. The website’s Create an account page makes one in your browser, and so do the ghost command-line client and the desktop app: it is the same file for all three. For the website alone, the account key can also set a generated website password.

The Create an account page (/account/new, linked from Log in and About) makes the account key in your browser with its random number generator. The key never leaves the browser: the page signs requests with it there and sends only the signatures and the public keys, and it keeps nothing in the browser’s storage.

  • Generate an account key shows the key’s ID and the key itself, one line that starts with gigahost-account-seed-v1:, as dots until you choose Show.
  • Download account.seed saves the seed file that ghost and the desktop app read, and Copy puts the line on the clipboard, for a password manager.
  • Continue waits until you tick I saved my account key, because the page cannot show the key again: once you go on, it is only in the copy you kept.

The next step on the same page activates the account.

  • By default, the account key is stored at $XDG_CONFIG_HOME/ghost/account.seed, or ~/.config/ghost/account.seed when XDG_CONFIG_HOME is not set.
  • A different location can be set with GHOST_SEED_FILE or --seed-file.
  • The account.seed the website downloads is this file. ghost key import --from account.seed puts it where ghost reads it (the default path, or the one GHOST_SEED_FILE or --seed-file names), private to your user. Without --from, the import asks for the line a password manager keeps, hidden as you paste it, or reads it from standard input. Afterwards it shows the key’s public identities and whether the key has an account yet. The downloaded file stays where it was, so you can delete it once the key is kept safely elsewhere.
  • An import does not overwrite an existing account key. The same key is left as it is. A different one is replaced only with --replace, which first keeps the current file beside it as account.seed.replaced-<UTC time>, so no key is lost.
  • The desktop app does the same with Import account key, from a file or a pasted line.
  • Moving the file to the default path yourself, with mode 0600, or naming it with --seed-file, also works.
  • Generation does not overwrite an existing account key.
  • key generate creates the account key’s directory, and any missing one above it, for your user alone (mode 0700). A directory that exists keeps its mode, so an existing ~/.config/ghost needs chmod 700 to be private.

An offline copy of this file is the way back into the account if the machine is lost. The next step is to fund and activate the account.

After Continue, the Create an account page offers two ways to open the account:

  • Sign up with GitHub, with the trial credit while trials are open: the page asks for the sign-up, then opens the same confirmation page as ghost account signup --github and goes on to GitHub. When you come back from GitHub’s sign-in, the account is made and this browser is logged in to it. See Signing up with GitHub.
  • Activate with an MMX deposit: the page shows the deposit address, the minimum, the confirmations and the current exchange rate, as ghost account activation-terms prints them, and your deposit memo, each with a copy button. After you send the deposit, Wait for my deposit has the page check for it every 20 seconds, for up to an hour, and log you in once the account is made. While it waits, the browser asks before the page is closed. Closing it is fine too: logging in later with the account key offers the same step and opens the account once the deposit is confirmed. See Funding your account for how a deposit is credited.

You can start an account without sending MMX by signing in with GitHub. The platform then creates the account, linked to your GitHub account. While trials are open and your GitHub account qualifies (see Who gets the trial credit), the account comes with a trial credit; otherwise it starts without credit, with a $0 balance, and an MMX deposit adds funds when you want to rent. An account key comes first.

ghost key generate
ghost account signup --github

ghost account signup --github prints a link and opens it in your browser if it can. The sign-in with GitHub needs to happen within 10 minutes. ghost waits, then prints the new account’s alias, the GitHub login it was linked to and whether the trial credit came with it (if not, why, and the deposit memo that adds funds), and the next steps. If the link expires, running the command again gives a new one. Adding --no-wait prints the claim and exits, and ghost account github-status CLAIM_ID reads it once.

The link is a bearer link: whoever opens it and signs in with GitHub completes the claim. The page it opens asks first what the claim is for, and ghost prints the GitHub login that completed it, so you can see it was yours.

A sign-up while trials are closed, or with a GitHub account that cannot have the trial credit (see Who gets the trial credit), still makes the account, without credit: a normal account with a $0 balance and none of a trial’s limits. Adding funds with an MMX deposit to its deposit memo lets it rent.

A GitHub account that is linked to an account cannot sign up; log in with GitHub reaches that account. Once unlinked from it, the GitHub account can sign up another account, or be linked again; the trial credit still comes once per GitHub account.

An account made with a deposit can link one GitHub account. The link lets you log in with GitHub, and a GitHub account that qualifies brings the trial credit with the first link.

ghost account link-github
ghost account unlink-github --yes

ghost account link-github is signed with the account key, opens a link the same way, and prints “Linked @login” and whether the credit came with it. ghost account unlink-github ends the link, and with it the website sessions a GitHub login began; it asks for --yes. ghost account show lists the linked GitHub account, as a github row with @login (linked DATE), or -.

An account links one GitHub account at a time, and a GitHub account links to one account at a time. The credit that comes with a link to an account made with a deposit carries none of the trial’s limits listed under What a trial gives: it only pays the charges of instances on the platform’s own hosts. A GitHub account that has brought the trial credit once brings it to no account again, also after an unlink.

  • A trial credit (currently $10) that lasts a number of days (currently 14). It pays the charges of instances on the platform’s own hosts before your balance does, expires on its date, and cannot be paid out. It counts toward your protected balance, so new rentals and backups leave $5 of it for the instances you run.
  • Until the account adds funds, the trial is limited: a few instances at once (currently 2), each of 1 vCPU with a Shared IP, on the hosts the platform itself runs; backups work as for any account, paid from the credit first. A trial sends no outgoing mail (TCP ports 25 and 465) and cannot offer hosts. A request over a limit gets trial_limit.
  • Adding funds lifts the limits at once. The same key and instances stay, and the credit still expires on its date.

ghost account show shows the trial’s credit left, its end and whether its limits still hold.

One credit for each GitHub account, ever, whichever account it is linked to, and only for a GitHub account that is at least a minimum age (currently 90 days), while trials are open. The credit comes with the first link that qualifies, a sign-up or a link. A sign-up or a link of a GitHub account that does not qualify, or made while trials are closed, is accepted without the credit. A credit that comes later with a link to an account a GitHub sign-up made, which has not added funds, has a trial’s limits until it does; any other account has it without them. An account key that already has an account cannot sign up again, a GitHub account linked to an account cannot sign up, a GitHub account is linked or signs up at most five times a day, and the platform limits how many sign-ups start each hour.

What Gigahost keeps about your GitHub account

Section titled “What Gigahost keeps about your GitHub account”

GitHub is told only that a sign-in happened, and the sign-in asks for no more than your public profile. Gigahost keeps:

  • the GitHub account’s numeric ID, the login names it was seen under, and its creation date;
  • when the account was linked and unlinked.

It keeps no OAuth token and no email address. These records stay after you unlink, as long as the account’s other records, to identify the holder of an account when the law requires it, and to turn away a second trial credit.

Gigahost keeps these values separate:

Identifier Example What it is for
Account alias gh-k3m7p2qa The short, stable name shown in the website and support workflows. It grants no authority and remains the same when keys change.
Deposit memo 16 characters Derived from the current owner public key. It is the exact memo for MMX deposits and is not an account ID.
Account UUID Used only for database relationships; it is not the account identity shown in the UI.

After an account key migration, the previous deposit memo remains linked to the same account, so a payment already in flight is not lost. The newest memo is the one for new payments.

Private ghost commands derive an Ed25519 owner key from the account key and sign each request. The signature covers the method, path and query, exact body, timestamp, random nonce, and any idempotency key.

The account key and private keys never leave the client. There is no bearer token, CLI session token or website session token to copy, store or configure.

HTTPS is the right choice for any non-loopback API endpoint. Signatures authenticate a request, but encryption is still needed to hide its contents and metadata in transit.

The account can hold multiple authentication public keys. The current client uses the unrestricted owner key. List the registered and retired keys with:

ghost account auth-keys
ghost account ssh-keys add --label laptop --file ~/.ssh/id_ed25519.pub
ghost account ssh-keys list
ghost account ssh-keys remove KEY_UUID

The account saves the SSH public keys of the machines you work from, each under a label, for new instances. The website’s Account page lists them as “SSH keys”.

  • ghost instance create and ghost instance reinstall install every saved key unless --ssh-key or --ssh-key-file names the keys.
  • The website offers the saved keys, checked, beside the key field when you rent or reinstall.
  • An instance keeps the keys it was made with; changing the saved keys later changes no instance.
ghost account login

The returned login_url expires, so it is best opened soon.

The first page after the login says which account you logged in as (“Logged in as gh-…”).

Log in with your account key, on the Log in page, takes the account.seed file or its pasted line. The browser signs a login link with the key, as ghost account login does, opens it, and forgets the key: the key is not sent, and the file and the field are emptied once read.

  • A key whose account is not made yet gets the activation step of the Create an account page, with a GitHub sign-up or the deposit’s terms and its memo. This is how an activation left waiting goes on. The step shows the key ID next to the memo. A pasted line has no checksum, so a line typed with one character wrong reads as another key, whose account the saved key could never reach; comparing the key ID and the memo with the ones the Create an account page or ghost key inspect showed, before a deposit or a sign-up, keeps the account with the key you saved.
  • A key retired by an account key migration is told so, with the time of the migration: the new key is the one that logs in.
  • A signature the website refuses usually means another account’s key, or a computer clock that is far off. The page corrects a clock a little off on its own; a clock set right fixes the rest.

A session begun with the account key is a login link’s session.

  • A link is short-lived and single-use: it works once, for a few minutes.
  • Its secret is carried in the URL fragment, redeemed by client-side JavaScript, and then removed from the address bar.
  • It creates a browser session without sending your account key or private key to the website. Gigahost does not store the raw login and session secrets.
  • If a link does not log you in, the login page says why: the link was already used, it was cancelled when every website session of the account was ended, or it expired. ghost account login makes a new one, which can be opened in the same tab.

A session lasts about 7 days and ends after 24 hours unused.

Rarely, right after a login, a page says that its server has not caught up with your login yet. You are still logged in, and trying again a few seconds later shows the page.

Creating another website session needs no email or password-reset workflow: the account key makes a new link, or sets a new website password.

  • Log out, in the account menu at the right of the website’s header, ends this browser’s session and clears its cookie.
  • Log out everywhere, on the Account page (/account), ends every website session of the account, including the current one, and cancels unused login URLs.
  • The Account page also lists every website session, with how it began (a login link or the website password), the key that made the link or set the password, when it was last used and when it ends, and an End button for each. It also lists the account’s authentication keys.

Ending every session is the remedy when a browser you logged in from is lost or shared, or a login URL may have leaked.

Ending sessions affects neither the CLI’s authentication keys nor the website password, so your CLI keys keep working. A website session can request a provider payout, but it cannot change the address payouts go to; see The payout address.

An account can also keep a password for the website, so you can log in from a browser without the CLI at hand.

ghost account set-password # draw one and show it once
ghost account set-password --expires-in 90 # one that stops working in 90 days
ghost account set-password --print # only the password, for a password manager
ghost account remove-password # turn password login off

The website’s Log in page (/login) then takes the account alias and the password.

Only the account key sets the password: with ghost, the Gigahost desktop app’s Account screen, or the website’s Account page, which signs the request in the browser with your account key (a file or a pasted line). A website session alone cannot set or change it, so someone holding a stolen website session cannot take the account over.

On the Account page, Set a password (or Change the password when one is set) takes the account key and, if you like, a number of days after which the password stops working. The page then shows the new password once, with Copy and I saved it. The browser makes the password and keeps nothing of it: only the public key of the login key it derives goes to Gigahost. Remove the password asks first, on the page, and ends the website sessions the password began.

  • It is generated and not chosen: 16 characters of letters, digits and - . ! ? @, without characters that are easy to confuse when read (0 and O, 1, l and I).
  • ghost and the website show it once, so a password manager is the place for it. --print writes only the password.
  • The browser derives a key from the alias and the password and signs a single-use challenge with it: the password itself is never sent to Gigahost, and Gigahost does not store it. The form needs JavaScript.
  • After a few failed attempts from one address, the form stops accepting attempts for a while. ghost account login still works.
  • Running ghost account set-password again draws a new password: the old one stops working and the website sessions it began end. Removing it ends them too. On the website’s Account page this reaches the session you are using, if it began with the old password: the page keeps the new password on screen until you choose I saved it, and you log in again with it.
  • Log out everywhere and ghost account revoke-sessions end sessions but keep the password. If a lost device had it saved, a new password is needed as well.
  • A forgotten password cannot be reset by email. The account key sets a new one.
  • An expiry is your choice and off by default (--expires-in DAYS, 1 to 3650). ghost account show and the website’s Account page show when the password was set and when it expires.
  • An expired password no longer logs in, and the login page says so. The sessions it began keep their own end.

A password session has no more rights than one begun by a login link. What needs the account key still needs it, which the website’s pages ask for and sign in the browser: minting login links, the website password, linking GitHub and the payout address. Migrating the account key and approving a hosted backup’s restore stay with ghost and the desktop app.

A GitHub session is like a password session: everything a renter does on the website, but it never counts as a fresh login, so it cannot do what only a login link allows. Unlinking GitHub ends the GitHub sessions.

Account key migration needs both the current account key and an independently generated replacement.

  1. Generating the replacement, and making an offline copy of it:

    ghost key generate --output "$HOME/.config/ghost/account.next.seed"
  2. Migrating:

    ghost account migrate-seed \
    --new-seed-file "$HOME/.config/ghost/account.next.seed" \
    --yes
  3. Selecting the replacement for later commands:

    export GHOST_SEED_FILE="$HOME/.config/ghost/account.next.seed"
    ghost account show
  • The current owner key authorizes the API request, and the replacement owner key separately signs the migration statement.
  • Gigahost then changes the key epoch atomically, revokes every previous authentication key and web session, and installs the new public authentication, billing, and recovery keys.
  • It revokes every existing login URL and website session, and ends the website password.
  • The account alias, balance, instances, and provider history do not change.
  • A request the previous account key signs from then on, such as a --wait still following a job or ghost account activate, gets auth_key_retired (401), which names the time of the migration.

Keeping the previous account key for old backups

Section titled “Keeping the previous account key for old backups”

You authenticate with the new account key and select the old one only for recovery when restoring such a backup; see Restore after an account key migration.

What an account is charged, its instances’ balance holds and the platform’s limits are on Pricing and billing.

A provider’s earnings, its payout address and payouts are on Payouts.