---
title: "Infra CLI 2.0: One Key Pulls Images, One Key Reaches Storage"
slug: "infra-cli-2-two-aws-keys-config-7"
date: "2026-10-30"
tag: "Infrastructure"
summary: "Infra CLI 2.0 provisions ibl.ai on AWS, GCP or an existing server against the 7.x declarative config system, takes separate AWS keys for pulling images and for the platform's own storage, adds NODE_ID, OpenRouter as the LLM key and S3 static and media buckets, and stops rather than half-configuring a server on an old CLI."
author: "ibl.ai Engineering"
repo: "iblai/infra-cli"
linkedin: |
  Infra CLI 2.0 provisions ibl.ai on your own AWS, GCP or bare-metal server with two AWS keys instead of one: one that only pulls container images, one that reaches the platform's storage.

  The point is scope. The image-pull key becomes the server's default AWS profile and never reaches the platform's settings.

  The storage key is optional, covers S3 media, SCORM uploads and SNS alerts, and if you skip it the server keeps whatever it already has. Each key can be cut to exactly its job.

  Setup now targets the 7.x declarative config system (init, config set, secrets set or generate, then an explicit render) and checks the installed CLI first, stopping rather than half-configuring a server on an older one.

  Also in 2.0: NODE_ID for log groups, OpenRouter as the deployment's LLM key, and S3 buckets for static files and media.

  1,109 passing tests. Install is a clone and one uv command; the repo is MIT.

  With ibl.ai you own all the code and the data: the installer is open source, the platform runs on infrastructure you control, it is model-agnostic across any LLM, and there is no per-seat pricing.

  #iblai #AgenticAI #EnterpriseAI #SelfHosted #AWS #GCP #Infrastructure
---

**ibl.ai's open-source Infra CLI reached 2.0 on October 12, 2026: it provisions the platform on AWS, GCP or an existing server against the 7.x declarative config system, takes one AWS key for pulling container images and a separate, optional key that reaches the platform's own storage, and refuses to half-configure a server on an older CLI, because on ibl.ai you own all the code and the data.**

Infra CLI is the MIT-licensed installer at [iblai/infra-cli](https://github.com/iblai/infra-cli): Terraform for the infrastructure, Ansible for the application, and a wizard that walks through cloud, credentials, topology, compute, network and domain.

The [2.0.0 release](https://github.com/iblai/infra-cli/releases/tag/v2.0.0) is the first major release since 1.0; its mirror on this site is at [Infra CLI](/developer/infra-cli), and the deployment posture it serves is described at [On-premise deployment](/on-premise-deployment).

## What does Infra CLI 2.0 change for a self-hosted ibl.ai?

Three things, all about who holds which credential and how a server is configured.

<table style="width:100%; border-collapse:collapse; margin:1.5rem 0; font-size:0.95rem;">
  <thead>
    <tr style="background:#f5f5f0; border-bottom:2px solid #2175C5;">
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">Change</th>
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">Before 2.0</th>
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">In 2.0</th>
    </tr>
  </thead>
  <tbody>
    <tr style="border-bottom:1px solid #e5e7eb;">
      <td style="padding:0.75rem;"><strong>AWS keys</strong></td>
      <td style="padding:0.75rem;">One key pulled images and served as the platform's own AWS credential</td>
      <td style="padding:0.75rem;">Two keys: an image-pull key, which also carries backup uploads by default, and an optional storage key, each scoped to its job</td>
    </tr>
    <tr style="border-bottom:1px solid #e5e7eb;">
      <td style="padding:0.75rem;"><strong>Config system</strong></td>
      <td style="padding:0.75rem;">The legacy config system: <code>ibl config save</code> with implicit rendering</td>
      <td style="padding:0.75rem;">The 7.x declarative model: init, config set, secrets set or generate, then an explicit render</td>
    </tr>
    <tr style="background:#f0f9ff; border-bottom:1px solid #e5e7eb;">
      <td style="padding:0.75rem;"><strong>Old CLI on the server</strong></td>
      <td style="padding:0.75rem;">No version gate; the playbooks targeted the pre-7.x CLI</td>
      <td style="padding:0.75rem;">Setup checks the installed CLI and stops if it is older than 7.0.0</td>
    </tr>
  </tbody>
</table>

The release was validated on platform images release 1.277.0 with the 7.24.0 platform CLI, and the test suite stands at 1,109 passing tests.

## Why does the installer now take two AWS keys instead of one?

Because a deployment whose registry access and S3 access live in different AWS accounts or IAM users had no way to say so, and the single key was handed to the platform as its S3 key.

Pulling container images is a deploy-and-update concern; storing media and SCORM uploads is the running platform's concern. One key doing both had to be scoped to both.

<table style="width:100%; border-collapse:collapse; margin:1.5rem 0; font-size:0.95rem;">
  <thead>
    <tr style="background:#f5f5f0; border-bottom:2px solid #2175C5;">
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">Key</th>
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">Variables</th>
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">What it does</th>
      <th style="text-align:left; padding:0.75rem; color:#5f6368;">Where it lives</th>
    </tr>
  </thead>
  <tbody>
    <tr style="border-bottom:1px solid #e5e7eb;">
      <td style="padding:0.75rem;"><strong>Image-pull key</strong> (required)</td>
      <td style="padding:0.75rem;"><code>AWS_ACCESS_KEY_ID</code> / <code>AWS_SECRET_ACCESS_KEY</code></td>
      <td style="padding:0.75rem;">Pulls the platform container images; needs ECR pull on the image repositories only. Backup uploads use it by default.</td>
      <td style="padding:0.75rem;">The server's default AWS CLI profile; never reaches the platform's own settings</td>
    </tr>
    <tr style="background:#f0f9ff; border-bottom:1px solid #e5e7eb;">
      <td style="padding:0.75rem;"><strong>Storage key</strong> (optional)</td>
      <td style="padding:0.75rem;"><code>S3_ACCESS_KEY_ID</code> / <code>S3_SECRET_ACCESS_KEY</code>, or the wizard prompt</td>
      <td style="padding:0.75rem;">S3 storage, SCORM uploads, and SNS alerts when a topic is configured</td>
      <td style="padding:0.75rem;">The platform's own secrets file on the server, <code>/ibl/secrets.yml</code>; needs the buckets, plus <code>sns:Publish</code> only when a topic is configured</td>
    </tr>
  </tbody>
</table>

The wizard offers a separate key, the same key, or skip. If the storage key is left unset, nothing is written: a fresh server renders without it, and `iblai infra resetup` keeps the key the server already has.

With buckets set and no storage key, setup stops before touching the server and says so.

AWS credentials are required on every deployment, including GCP and bare metal, because the images come from the registry; they are not for hosting, and object storage stays on AWS S3 even for a GCP deployment.

## What does Infra CLI 2.0 setup look like on ibl.ai's 7.x config system?

The 2.0 playbooks drive the platform's declarative config model: `ibl init`, `ibl config set`, `ibl secrets set` or `ibl secrets generate`, then an explicit `ibl render`.

Setup requires the platform CLI at 7.0.0 or later and reads the release from one knob, `PROD_IMAGES_TAG`, which must name a platform images release that pins a 7.x CLI.

<div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:0.75rem; margin:1.5rem 0;">
  <div style="border:1px solid #e5e7eb; border-radius:0.5rem; padding:0.75rem;"><div style="color:#2175C5; font-weight:600; font-size:0.8rem;">1 · Install</div><div style="font-size:0.9rem;">Clone the repo and <code>uv sync</code> (<code>--extra gcp</code> for GCP), or <code>uv tool install</code> from git; Python 3.11+ and Terraform on PATH</div></div>
  <div style="border:1px solid #e5e7eb; border-radius:0.5rem; padding:0.75rem;"><div style="color:#2175C5; font-weight:600; font-size:0.8rem;">2 · Permissions</div><div style="font-size:0.9rem;"><code>iblai infra permissions --check</code> dry-runs the cloud policy before anything is created</div></div>
  <div style="border:1px solid #e5e7eb; border-radius:0.5rem; padding:0.75rem;"><div style="color:#2175C5; font-weight:600; font-size:0.8rem;">3 · Provision</div><div style="font-size:0.9rem;">The wizard: cloud, credentials, topology, compute (100 GB disk minimum), network, domain</div></div>
  <div style="border:1px solid #e5e7eb; border-radius:0.5rem; padding:0.75rem;"><div style="color:#2175C5; font-weight:600; font-size:0.8rem;">4 · Setup</div><div style="font-size:0.9rem;"><code>iblai infra setup</code> installs Docker, the platform CLI and the application; it is the only step on an existing server</div></div>
  <div style="border:1px solid #e5e7eb; border-radius:0.5rem; padding:0.75rem;"><div style="color:#2175C5; font-weight:600; font-size:0.8rem;">5 · Open</div><div style="font-size:0.9rem;">The app is at <code>https://learn.&lt;your-domain&gt;</code></div></div>
</div>

On the 7.x runtime, fresh installs and re-runs were fixed in four places: the Data Manager (DM) bootstraps without a manual launch, OAuth and OIDC credential rows are updated in place, every agent gets the settings row that chat reads, and the health-check agents pass the DM readiness gate.

`iblai infra resetup` no longer rotates the keys that encrypt stored data.

## What else ships in Infra CLI 2.0?

- **`NODE_ID`**, set with `--node-id`, in `.env` or in the wizard; `ibl render` requires it, and it defaults to the project name.
- **OpenRouter as the LLM key** (`OPENROUTER_API_KEY` or the wizard), stored as the deployment's gateway credential; the platform's default agents run on the gateway models (`iblai-pro` / `iblai-fast`), which only an OpenRouter key serves, so chat works with no further setup while tenants stay on the deployment's keys.
- **S3 storage for DM static files and media** through `S3_STATIC_BUCKET`, `S3_MEDIA_BUCKET` and `S3_REGION`; the platform keeps media, static assets and backups in three buckets that AWS provisioning creates for you.
- **SPA restarts** follow the enabled SPAs instead of a fixed list, and the AI call service stays off until a call server is connected.
- **`service-update`** installs from the configured organization and repositories, and the GitHub token is kept out of install URLs.

## How do you upgrade an existing ibl.ai deployment to Infra CLI 2.0?

Install the tool with `uv tool install --force git+https://github.com/iblai/infra-cli` and confirm `iblai --version` reports 2.0.0. Then pick a 7.x release by setting `PROD_IMAGES_TAG` or answering the wizard prompt.

An `.env` file that already names S3 buckets must also set the storage key, repeating the image-pull key there if one key does both jobs; `.env.setup.example` in the repo shows the layout.

Servers still on the 5.x platform CLI need the config migration first, documented in the repo's `docs/config-6x-migration.md`.

## Why does an open-source installer matter to a buyer of self-hosted AI?

Because self-hosting is only real if someone can actually run it.

Most managed AI vendors cannot hand you an installer, since there is nothing of theirs to install; ibl.ai ships one under an MIT license, with the AWS, GCP and bare-metal paths in the same wizard, and the platform it installs comes with a Full Code License.

That is the sovereignty claim made concrete: the images pull with one scoped key, your data lives in buckets you own under a key that lives only in the platform's secrets file on your own server, any model answers through the LLM key you choose, and there is no per-seat pricing.

1.6M+ users across 400+ organizations run the platform this way, including NVIDIA, MIT, and Syracuse University.

## Want to see a deployment provisioned end to end?

We will run the wizard against a cloud account of your choosing and walk through the two-key model and the 7.x config, in a 30-minute call. [Book a 30-minute demo](https://cal.com/iblai/30min) or [talk to the ibl.ai team](/contact) — ibl.ai is family-owned and operated from New York, NY.
