Quick start after purchase

You’ve just bought a license β€” this page takes you from an empty StarterKit Foundation project to a working composer update. The checkout success page and the purchase email show the same steps with your real license key, email, and licensing host already filled in β€” copy the ready-made line from there rather than retyping it here.

1. Your license key

The license key is the Composer HTTP-basic password; the email address you used at checkout is the username. Keep the key private β€” never commit it to a repository or paste it into a public issue.

2. Composer credentials β€” config/environment/.env.secret

Add one line to config/environment/.env.secret in your StarterKit project β€” unescaped JSON, one line, no spaces:

COMPOSER_AUTH={"http-basic":{"<licensing-host>":{"username":"<your-email>","password":"<your-license-key>"}}}

The file is gitignored β€” never commit it. The Composer container reads COMPOSER_AUTH from it automatically. See Environment & Secrets for the full environment file layout.

3. CI/CD (GitHub Actions) β€” repository secret

GitHub β†’ Settings β†’ Secrets and variables β†’ Actions β†’ New repository secret. Name it COMPOSER_AUTH and paste only the value, with no COMPOSER_AUTH= prefix. GitHub requires the escaped form (every " backslash-prefixed), which is why it differs from step 2:

{\"http-basic\":{\"<licensing-host>\":{\"username\":\"<your-email>\",\"password\":\"<your-license-key>\"}}}

See CI/CD Deployments for how the deploy pipeline consumes this secret.

4. composer.json β€” repository and modules

A StarterKit Foundation project already ships both entries below β€” this step is only for a project that lost them, or one that was not built on Foundation. repositories[0] points at the licensing repository, and one require entry per granted module is added at "*"; constraints are left at * and should be pinned per project.

{
    "repositories": [
        {
            "type": "composer",
            "url": "https://<licensing-host>"
        }
    ],
    "require": {
        "solidbunch/<module-slug>": "*"
    }
}

5. Install the modules

From the project root, run Composer inside its dedicated container β€” never on the host, never docker compose run directly. See Composer usage for why: ownership/UID mismatch and version skew.

make run composer
composer update

Granted modules land in kit-modules/.

Verify the install

Check composer.lock: a licensed module has a real "dist" block ("type": "zip", a real URL). Without valid credentials, Composer degrades the package to "type": "metapackage" instead of failing loudly β€” that is the single most important thing on this page.

grep -A4 '"name": "solidbunch/<module-slug>"' composer.lock

A good entry looks like this:

"name": "solidbunch/<module-slug>",
"dist": {
    "type": "zip",
    "url": "https://<licensing-host>/..."
}

A bad entry (no real credentials, or license does not grant the module) looks like this:

"name": "solidbunch/<module-slug>",
"type": "metapackage"

Also run ls kit-modules/ β€” it should show real directories containing code, not just an empty or missing folder.

When it does not work

  • 401 Unauthorized / “Invalid credentials” while downloading from the licensing repo. Wrong email or wrong key β€” a typo, a trailing space, wrong quoting in the JSON, or the escaped form used in .env.secret instead of the unescaped one. Fix: re-copy both values from the success page or the purchase email, then re-run make run composer and composer update.
  • Package installed but composer.lock says "type": "metapackage". Credentials worked, but the license does not grant that module (for example, a Free/Pro tier asked for an Enterprise-only module). Nothing is broken locally β€” the fix is an upgraded license, not a config change.
  • Everything worked before and now returns the same 401-style failure. The license has expired β€” not a typo. Fix: renew the license, then re-run the install; the key itself does not change on renewal unless the storefront says otherwise.

Next steps