<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Saif Ali</title>
    <description>The latest articles on Forem by Saif Ali (@sali_ac161a1b71406354896c).</description>
    <link>https://forem.com/sali_ac161a1b71406354896c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3780544%2F353acf11-059d-471c-a779-825d98da6c00.png</url>
      <title>Forem: Saif Ali</title>
      <link>https://forem.com/sali_ac161a1b71406354896c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sali_ac161a1b71406354896c"/>
    <language>en</language>
    <item>
      <title>NEXUS AI RBAC</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sat, 25 Apr 2026 22:38:05 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/nexus-ai-rbac-5bk1</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/nexus-ai-rbac-5bk1</guid>
      <description>&lt;h1&gt;
  
  
  RBAC deep dive: roles, scopes, and least privilege
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; April 21, 2026&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Category:&lt;/strong&gt; Security · Platform&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reading time:&lt;/strong&gt; 14 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Author:&lt;/strong&gt; NEXUS AI Team&lt;/p&gt;



&lt;p&gt;A developer leaves the company on Friday. By Monday, their credentials still open three production deployments, two billing pages, and a secrets vault they haven't touched in four months.&lt;/p&gt;

&lt;p&gt;That's not a people problem. That's an access model problem.&lt;/p&gt;

&lt;p&gt;Role-Based Access Control (RBAC) is how NEXUS AI answers the question every engineering org eventually asks: &lt;em&gt;who can do what, to which resources, and how do we prove it?&lt;/em&gt; This post goes deep — the role hierarchy, how scopes layer on top of roles, how least privilege works in practice, and how to design an access model your team will actually maintain.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why RBAC matters more as your team scales
&lt;/h2&gt;

&lt;p&gt;When it's just you, every door being open is convenient. When you have a team of 12 across three environments, every door being open is a liability.&lt;/p&gt;

&lt;p&gt;The breach surface for a SaaS product running on cloud infrastructure is rarely the infrastructure itself. It's the humans and automated systems that have standing access to it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A contractor with &lt;code&gt;admin&lt;/code&gt; access granted for a two-week engagement — and never revoked.&lt;/li&gt;
&lt;li&gt;A CI/CD token with full &lt;code&gt;secrets:write&lt;/code&gt; permission because it was "easier to set up that way."&lt;/li&gt;
&lt;li&gt;A junior developer who can redeploy production because the staging role got copy-pasted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NEXUS AI's RBAC system is designed to make the right permission easy to grant and hard to accidentally expand. Least privilege is the default, not a setting you have to configure.&lt;/p&gt;


&lt;h2&gt;
  
  
  The role hierarchy
&lt;/h2&gt;

&lt;p&gt;NEXUS AI defines four built-in roles. They are ordered by permission level — each role is a strict superset of the one below it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Who it's for&lt;/th&gt;
&lt;th&gt;What it controls&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Viewer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stakeholders, auditors, QA observers&lt;/td&gt;
&lt;td&gt;Read-only access to deployments, logs, and metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Engineers doing day-to-day deployment work&lt;/td&gt;
&lt;td&gt;Deploy, redeploy, rollback; read secret names (not values)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Admin&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Team leads, platform engineers&lt;/td&gt;
&lt;td&gt;Full control of deployments, secrets, tokens, and members&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Owner&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Founder, CTO, or designated security lead&lt;/td&gt;
&lt;td&gt;Everything Admin can do + delete the organization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One organization has exactly one Owner. Ownership can be transferred, but not duplicated. This prevents the "everyone is an Owner" pattern that makes incident response a guessing game.&lt;/p&gt;
&lt;h3&gt;
  
  
  Viewer
&lt;/h3&gt;

&lt;p&gt;Viewers can observe — nothing more.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ View deployment status (running, stopped, failed)
✓ Read build and runtime logs
✓ See deployment metadata (region, container count, uptime)
✓ View audit log summaries
✗ Trigger any action (deploy, redeploy, rollback, stop)
✗ See secret names or values
✗ Create or revoke Access Tokens
✗ Invite or remove team members
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use Viewer for: product managers monitoring deploy status, customer success checking uptime, external auditors reviewing activity logs, read-only access for contractors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer
&lt;/h3&gt;

&lt;p&gt;Developers can act on deployments. They cannot change platform configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Everything Viewer can do
✓ Deploy, redeploy, rollback, stop deployments
✓ View secret names (DATABASE_URL, STRIPE_KEY) — never values
✓ Create Access Tokens scoped to deploy:read and deploy:write only
✗ Create, update, or delete secrets
✗ Create tokens with admin or secrets:write scope
✗ Invite or remove organization members
✗ View billing or usage data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Developer can push code and redeploy. They cannot change the secrets their code reads. The separation is intentional: it means a Developer-level compromise cannot extract production credentials, only trigger a redeploy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Admin
&lt;/h3&gt;

&lt;p&gt;Admins own the platform configuration for an organization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Everything Developer can do
✓ Create, update, and delete secrets
✓ Create Access Tokens with any scope
✓ Invite members and assign roles (up to Admin)
✓ View and export audit logs
✓ Manage domains, billing, and usage
✗ Delete the organization
✗ Transfer ownership
✗ Grant Owner role to another member
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Limit Admin to people who actually need to configure secrets or onboard team members. In a 10-person startup, that's usually two or three people. In a 100-person company, it's a dedicated platform team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Owner
&lt;/h3&gt;

&lt;p&gt;The Owner role is structurally different from Admin — it's not just "more permissions," it's accountability. Only one member holds it, and it carries the ability to perform irreversible actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Everything Admin can do
✓ Delete the organization and all its resources
✓ Transfer ownership to another Admin
✓ Access all historical audit logs (including deleted members)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Owner should be the person who is accountable for the business — not necessarily the most technical. At a startup, that's the founding engineer or CTO. At an enterprise, it's the platform owner or CISO-designated lead.&lt;/p&gt;




&lt;h2&gt;
  
  
  How scopes work
&lt;/h2&gt;

&lt;p&gt;Roles define what a &lt;em&gt;human&lt;/em&gt; can do. Scopes define what a &lt;em&gt;token&lt;/em&gt; can do.&lt;/p&gt;

&lt;p&gt;When a Developer (or Admin) creates an Access Token, they can grant that token any scope up to — but not exceeding — their own permissions. A Developer cannot create a token with &lt;code&gt;secrets:write&lt;/code&gt; scope, because Developers cannot write secrets directly.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;scope containment&lt;/strong&gt;: tokens cannot be a privilege escalation vector.&lt;/p&gt;

&lt;h3&gt;
  
  
  The full scope table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;Read/Write&lt;/th&gt;
&lt;th&gt;What it permits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deploy:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;View status, logs, metadata for deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deploy:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write&lt;/td&gt;
&lt;td&gt;Create, redeploy, rollback, scale, stop deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;secrets:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;List secret names for a deployment (never values)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;secrets:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write&lt;/td&gt;
&lt;td&gt;Create, update, delete secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tokens:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;List tokens and their metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tokens:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write&lt;/td&gt;
&lt;td&gt;Create and revoke Access Tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;members:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;List organization members and their roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;members:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write&lt;/td&gt;
&lt;td&gt;Invite, remove, and change roles of members&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;billing:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;View usage statistics and invoices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;billing:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Write&lt;/td&gt;
&lt;td&gt;Update billing plan and payment method&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;logs:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;Read build logs, runtime logs, and audit logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;Full access equivalent to Admin role&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scopes compose. A CI token for a deployment pipeline typically needs &lt;code&gt;deploy:write&lt;/code&gt; and nothing else. A token for a read-only monitoring integration needs &lt;code&gt;deploy:read&lt;/code&gt; and &lt;code&gt;logs:read&lt;/code&gt;. An MCP integration for an AI agent doing deployment management might need &lt;code&gt;deploy:read,deploy:write,logs:read&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a precisely scoped token
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CI/CD: deploy-only, expires in 90 days&lt;/span&gt;
nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"github-actions-prod"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 90d

&lt;span class="c"&gt;# Monitoring integration: read-only, no expiry (rotate quarterly via calendar)&lt;/span&gt;
nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"datadog-integration"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:read,logs:read

&lt;span class="c"&gt;# AI agent with deployment management access&lt;/span&gt;
nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"claude-mcp-agent"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:read,deploy:write,logs:read &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 30d

&lt;span class="c"&gt;# Admin token for a one-time onboarding script (delete immediately after use)&lt;/span&gt;
nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"onboarding-script-2026-04-21"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; admin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 1d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last example — a short-lived &lt;code&gt;admin&lt;/code&gt; token for a specific script, destroyed after use — is exactly how temporary elevated access should work. No standing privileged access. No "just in case" tokens that accumulate over months.&lt;/p&gt;




&lt;h2&gt;
  
  
  Least privilege in practice
&lt;/h2&gt;

&lt;p&gt;Least privilege is not a policy you write. It's a discipline you build into your provisioning process. Here's what it looks like in a real NEXUS AI team across three common scenarios.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 1: Onboarding a new backend engineer
&lt;/h3&gt;

&lt;p&gt;Wrong approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New hire → Admin role → "they'll need it eventually"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New hire → Developer role
Week 1: pair with an Admin for any secrets work
Month 3: reassess — do they actually need Admin? (usually no)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Developer role covers 95% of what an active engineer does: deploy, redeploy, check logs, rollback a bad release. Secret creation is rare and can go through an Admin without slowing anyone down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Setting up a GitHub Actions pipeline
&lt;/h3&gt;

&lt;p&gt;Wrong approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus token create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"github-actions"&lt;/span&gt; &lt;span class="nt"&gt;--scopes&lt;/span&gt; admin
&lt;span class="c"&gt;# Stored in GitHub secrets as NEXUS_API_KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# One token per environment, deploy:write only&lt;/span&gt;
nexus token create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"github-actions-staging"&lt;/span&gt; &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write &lt;span class="nt"&gt;--expires&lt;/span&gt; 90d
nexus token create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"github-actions-prod"&lt;/span&gt; &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write &lt;span class="nt"&gt;--expires&lt;/span&gt; 90d

&lt;span class="c"&gt;# Store each in the corresponding GitHub environment secret&lt;/span&gt;
&lt;span class="c"&gt;# github.com/org/repo → Settings → Environments → staging → NEXUS_API_KEY&lt;/span&gt;
&lt;span class="c"&gt;# github.com/org/repo → Settings → Environments → production → NEXUS_API_KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Environment-scoped tokens mean a staging pipeline compromise cannot touch production. The &lt;code&gt;deploy:write&lt;/code&gt; scope means the pipeline can redeploy but cannot read or modify secrets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 3: Granting an external contractor temporary access
&lt;/h3&gt;

&lt;p&gt;Wrong approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contractor → Admin role → "we'll remove it when they're done"
(They're done. It's still there. Six months later: breach.)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Right approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Invite as Viewer — they can observe, not act&lt;/span&gt;
nexus member invite contractor@agency.com &lt;span class="nt"&gt;--role&lt;/span&gt; Viewer

&lt;span class="c"&gt;# If they need to trigger deploys, create a scoped token with explicit expiry&lt;/span&gt;
nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"contractor-agency-q2-2026"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 30d

&lt;span class="c"&gt;# Deliver the token via a secure channel. Calendar reminder for 29 days out.&lt;/span&gt;
&lt;span class="c"&gt;# At project end: revoke the token and remove the member&lt;/span&gt;
nexus token revoke tok_01HX9...
nexus member remove contractor@agency.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The token expires automatically even if you forget. The member removal is still important — it cleans up the audit trail and signals a clean handoff.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resource-level access: deployments and projects
&lt;/h2&gt;

&lt;p&gt;Roles apply at the organization level by default. But NEXUS AI also supports &lt;strong&gt;project-scoped membership&lt;/strong&gt; — isolating access to a subset of deployments within an organization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add a Developer to a specific project only&lt;/span&gt;
nexus project member add &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project&lt;/span&gt; payments-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--email&lt;/span&gt; engineer@company.com &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role&lt;/span&gt; Developer

&lt;span class="c"&gt;# They can now deploy payments-service/* deployments&lt;/span&gt;
&lt;span class="c"&gt;# They cannot see auth-service/*, user-service/*, or any other project&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Project-scoped access is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regulated workloads&lt;/strong&gt; — your payments team accesses the payments project; your analytics team accesses the analytics project. No overlap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tenant organizations&lt;/strong&gt; — agencies managing deployments for multiple clients. Each client's project is isolated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contractor access&lt;/strong&gt; — limit a vendor to exactly the project they're working on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Organization-level Admins retain visibility across all projects. Project-scoped Developers cannot see outside their project boundary.&lt;/p&gt;




&lt;h2&gt;
  
  
  RBAC and AI agents
&lt;/h2&gt;

&lt;p&gt;NEXUS AI's 37 MCP tools for Claude and AI agents operate under the same RBAC model as human callers. A token issued to an AI agent carries exactly the same scope enforcement — no exceptions.&lt;/p&gt;

&lt;p&gt;This matters because AI agents tend to be given more access than they need "because it's easier." An agent with &lt;code&gt;admin&lt;/code&gt; scope that goes wrong is a full organization compromise. An agent with &lt;code&gt;deploy:read&lt;/code&gt; that goes wrong reveals status information and nothing else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Designing safe agent access
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Read-only diagnostic agent&lt;/strong&gt; — Claude inspects logs, checks deployment health, surfaces anomalies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"claude-diagnostic"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:read,logs:read &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent cannot deploy, rollback, or change anything. It observes and reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment automation agent&lt;/strong&gt; — Claude reacts to CI signals and triggers redeployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"claude-deploy-agent"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:read,deploy:write,logs:read &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 30d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent can act on deployments. It cannot touch secrets, billing, or team membership.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Incident response agent&lt;/strong&gt; — Claude triages a production incident, can rollback if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Short-lived, manually issued during an incident&lt;/span&gt;
nexus token create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"claude-incident-2026-04-21"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:read,deploy:write,logs:read &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--expires&lt;/span&gt; 4h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4-hour expiry. The token disappears when the incident window ends. No standing elevated access for AI agents.&lt;/p&gt;

&lt;p&gt;The rule: grant an AI agent the minimum scope it needs to complete its defined task. Then set an expiry that matches the task duration — not "never" because that's convenient.&lt;/p&gt;




&lt;h2&gt;
  
  
  What RBAC cannot do
&lt;/h2&gt;

&lt;p&gt;Knowing the limits of any security control is as important as knowing what it covers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RBAC does not protect against a compromised Owner account.&lt;/strong&gt; The Owner role has full access. If an Owner's credentials are compromised, the attacker has full access. Protect Owner accounts with hardware MFA, not just TOTP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RBAC does not prevent a Developer from logging sensitive data.&lt;/strong&gt; If your application logs &lt;code&gt;process.env.DATABASE_URL&lt;/code&gt; at startup, that value appears in runtime logs — which Developers can read. Secret management starts with application code discipline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RBAC does not enforce network-level isolation.&lt;/strong&gt; A Developer with &lt;code&gt;deploy:write&lt;/code&gt; can push a container that opens a reverse shell. Pair RBAC with container security policies and network egress controls for workloads that require it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RBAC does not replace secrets rotation.&lt;/strong&gt; Least privilege reduces blast radius when a secret is compromised. Rotation reduces the window of exposure. Both are required for a complete security posture.&lt;/p&gt;




&lt;h2&gt;
  
  
  The access model audit
&lt;/h2&gt;

&lt;p&gt;Run this quarterly. It takes 20 minutes and it will find something to fix every time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List all organization members and their roles&lt;/span&gt;
nexus member list

&lt;span class="c"&gt;# List all active tokens with creation date and last-used date&lt;/span&gt;
nexus token list &lt;span class="nt"&gt;--show-last-used&lt;/span&gt;

&lt;span class="c"&gt;# Check for tokens with no expiry&lt;/span&gt;
nexus token list &lt;span class="nt"&gt;--no-expiry&lt;/span&gt;

&lt;span class="c"&gt;# Check for tokens unused in 30+ days&lt;/span&gt;
nexus token list &lt;span class="nt"&gt;--unused-since&lt;/span&gt; 30d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each token unused in 30+ days: revoke it. For each &lt;code&gt;admin&lt;/code&gt;-scoped token that isn't for a one-time script: replace it with narrower scopes. For each member at a role higher than their current responsibilities: downgrade it.&lt;/p&gt;

&lt;p&gt;The goal is to reach a state where every active token has a name that explains exactly what it does, an expiry that matches how long it needs to exist, and the minimum scope to do its job.&lt;/p&gt;




&lt;h2&gt;
  
  
  RBAC and compliance
&lt;/h2&gt;

&lt;p&gt;If you're in a regulated industry — healthcare, fintech, legal — RBAC is table stakes for compliance. NEXUS AI's RBAC system maps directly to common control requirements:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Compliance requirement&lt;/th&gt;
&lt;th&gt;NEXUS AI control&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Least-privilege access&lt;/td&gt;
&lt;td&gt;Role hierarchy + token scopes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Separation of duties&lt;/td&gt;
&lt;td&gt;Developers cannot write secrets; Owners are unique&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access review&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;nexus member list&lt;/code&gt;, &lt;code&gt;nexus token list&lt;/code&gt; for quarterly audits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privileged access management&lt;/td&gt;
&lt;td&gt;Admin and Owner roles with MFA enforcement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access revocation on termination&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;nexus member remove&lt;/code&gt; + &lt;code&gt;nexus token revoke&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit trail&lt;/td&gt;
&lt;td&gt;Append-only audit logs with actor, token ID, timestamp, and IP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Enterprise and Enterprise On-Prem plans include 90-day and indefinite audit log retention respectively. Logs are exportable to Datadog, Grafana, Splunk, or any SIEM via the audit log export API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checklist: production-grade RBAC setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Assign roles at the minimum level needed — start with Developer, escalate to Admin only when demonstrated necessary&lt;/li&gt;
&lt;li&gt;[ ] No team member should have Owner role unless they're accountable for the organization&lt;/li&gt;
&lt;li&gt;[ ] Every CI/CD pipeline uses a separate &lt;code&gt;deploy:write&lt;/code&gt; token per environment&lt;/li&gt;
&lt;li&gt;[ ] Every token has a name that identifies its purpose and a &lt;code&gt;--expires&lt;/code&gt; flag&lt;/li&gt;
&lt;li&gt;[ ] No &lt;code&gt;admin&lt;/code&gt;-scoped tokens in standing use — only for one-time scripts with 1-day expiry&lt;/li&gt;
&lt;li&gt;[ ] AI agent tokens scoped to exactly what the agent does (not &lt;code&gt;admin&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Quarterly access review: &lt;code&gt;nexus token list --unused-since 30d&lt;/code&gt; and &lt;code&gt;nexus member list&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Project-scoped membership for workloads that should be isolated (payments, healthcare, multi-client)&lt;/li&gt;
&lt;li&gt;[ ] Owner account protected with hardware MFA (YubiKey or equivalent)&lt;/li&gt;
&lt;li&gt;[ ] Offboarding runbook: member remove + all associated tokens revoke, same day&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can a Developer see their own Access Tokens after creation?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Token values are shown once at creation — never again. A Developer can list their tokens by name and ID (&lt;code&gt;nexus token list --mine&lt;/code&gt;), but the &lt;code&gt;token_value&lt;/code&gt; is never retrievable. If lost, rotate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to tokens when a member is removed?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tokens are scoped to the organization, not to the member who created them. Removing a member does not automatically revoke their tokens. Run &lt;code&gt;nexus token list --created-by email@company.com&lt;/code&gt; and revoke manually as part of offboarding. A future release will offer member-removal with automatic token revocation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a Developer escalate their own role?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No. Role changes require Admin or Owner. A Developer cannot call any API endpoint that modifies their own or another member's role.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does NEXUS AI handle role changes mid-session?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Role and scope changes take effect immediately. An active API session using a token that gets revoked will receive a &lt;code&gt;401 Unauthorized&lt;/code&gt; on the next call — there's no grace window for human sessions (only for the 5-minute deploy token rotation window).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a way to grant time-limited elevated access without creating a token?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Not currently at the role level — role changes are persistent until manually reverted. Use a short-lived &lt;code&gt;admin&lt;/code&gt;-scoped token for temporary elevated operations instead of upgrading a member's role. This keeps the audit trail cleaner and eliminates the "I forgot to downgrade them" failure mode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're on the Starter plan. Do we get RBAC?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. All four roles and the full scope system ship on every plan, including Starter at $29/mo. Project-scoped membership and audit log export are Enterprise features.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Access control works best when it's boring — when every token has a clear purpose, every role is appropriate, and your quarterly audit finds nothing to clean up. That state is achievable. It requires an initial setup investment of about two hours and 20 minutes of discipline every quarter.&lt;/p&gt;

&lt;p&gt;Start with your CI/CD tokens. Replace any &lt;code&gt;admin&lt;/code&gt;-scoped pipeline token with &lt;code&gt;deploy:write&lt;/code&gt;. That one change eliminates your largest standing access risk.&lt;/p&gt;

&lt;p&gt;For regulated workloads, compliance tooling, or teams larger than 20 engineers, the Enterprise plan adds SAML SSO, custom audit log retention, and dedicated security review. Reach out at &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;nexusai.run&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop shipping secrets. Start using a vault.&lt;/li&gt;
&lt;li&gt;MCP integration: 37 tools for Claude and AI agents&lt;/li&gt;
&lt;li&gt;Audit logs and compliance: what gets recorded and why&lt;/li&gt;
&lt;li&gt;How NEXUS AI deploys your app in under 5 minutes&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Least privilege is not paranoia. It's the discipline that makes incidents containable.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>Stop shipping secrets. Start using a vault</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sat, 25 Apr 2026 21:47:39 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/stop-shipping-secrets-start-using-a-vault-oi6</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/stop-shipping-secrets-start-using-a-vault-oi6</guid>
      <description>&lt;h1&gt;
  
  
  Stop shipping secrets. Start using a vault.
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; April 21, 2026&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Category:&lt;/strong&gt; Security · DevOps&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reading time:&lt;/strong&gt; 12 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Author:&lt;/strong&gt; NEXUS AI Team&lt;/p&gt;



&lt;p&gt;Leaked API keys cost companies an average of $1.2M per incident. Not because engineers are careless — because the tooling makes the wrong thing easy. &lt;code&gt;.env&lt;/code&gt; files committed to repos. Hardcoded credentials baked into container images. Production secrets copy-pasted into Slack for "temporary" handoffs that last six months.&lt;/p&gt;

&lt;p&gt;NEXUS AI ships a built-in Secrets Vault and a first-class Access Token system. This post covers exactly how both work, how they integrate at deploy time, and how to run a zero-plaintext secret configuration in your production environment — starting today.&lt;/p&gt;


&lt;h2&gt;
  
  
  The problem with secrets in 2026
&lt;/h2&gt;

&lt;p&gt;Most teams manage secrets in one of three ways:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;What goes wrong&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.env&lt;/code&gt; files in repos&lt;/td&gt;
&lt;td&gt;One &lt;code&gt;git log&lt;/code&gt; away from a breach. "Secret" scans never catch everything.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD environment variables&lt;/td&gt;
&lt;td&gt;Visible to anyone with repo access. Rotate one and you're editing 14 pipelines.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud secret managers (AWS Secrets Manager, GCP Secret Manager)&lt;/td&gt;
&lt;td&gt;Right idea, wrong integration. Requires service accounts, IAM glue, and a custom fetch layer in every app.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The common thread: secrets live somewhere they shouldn't, accessed by code that has more permission than it needs, with no record of who read what.&lt;/p&gt;

&lt;p&gt;NEXUS AI eliminates all three failure modes at the platform level.&lt;/p&gt;


&lt;h2&gt;
  
  
  The NEXUS AI Secrets Vault
&lt;/h2&gt;

&lt;p&gt;Every NEXUS AI project ships with an encrypted Secrets Vault. Secrets are encrypted at rest using &lt;strong&gt;AES-256-GCM&lt;/strong&gt; before they touch the database — the same cipher used by the U.S. Department of Defense for classified data at rest.&lt;/p&gt;
&lt;h3&gt;
  
  
  How encryption works
&lt;/h3&gt;

&lt;p&gt;When you store a secret, NEXUS AI:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Encrypts the value with AES-256-GCM using a derived key (scoped per organization).&lt;/li&gt;
&lt;li&gt;Stores only the ciphertext, the IV (initialization vector), and the auth tag.&lt;/li&gt;
&lt;li&gt;Never writes the plaintext to disk, logs, or any observable surface.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The encryption key itself is never stored alongside the ciphertext. It's derived at runtime from &lt;code&gt;SECRETS_ENCRYPTION_KEY&lt;/code&gt; — an environment variable you set once at the platform level and never touch again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Set via the NEXUS AI CLI&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;DATABASE_URL &lt;span class="s2"&gt;"postgres://user:pass@host:5432/db"&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;STRIPE_SECRET_KEY &lt;span class="s2"&gt;"sk_live_..."&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;OPENAI_API_KEY &lt;span class="s2"&gt;"sk-..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secrets are namespaced per deployment. A secret set for &lt;code&gt;api-prod&lt;/code&gt; is not visible to &lt;code&gt;api-staging&lt;/code&gt; — even if both deployments live in the same project.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the vault does NOT do
&lt;/h3&gt;

&lt;p&gt;No system is better described by its constraints than its capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The vault does &lt;strong&gt;not&lt;/strong&gt; store secrets in application containers. Secrets are injected at runtime as environment variables, never embedded in the image.&lt;/li&gt;
&lt;li&gt;The vault does &lt;strong&gt;not&lt;/strong&gt; expose secret values through logs. The observability pipeline redacts known secret patterns automatically.&lt;/li&gt;
&lt;li&gt;The vault does &lt;strong&gt;not&lt;/strong&gt; allow cross-tenant secret access. Secrets are scoped to an organization ID enforced at the query layer — not just the API layer.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Secure Configuration Injection
&lt;/h2&gt;

&lt;p&gt;When NEXUS AI deploys your application, secrets don't get "loaded" by your app at startup. They're injected into the container's environment by the runtime before the first process starts.&lt;/p&gt;

&lt;p&gt;The sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Deploy command issued
2. NEXUS AI fetches encrypted secrets for the target deployment
3. Secrets decrypted in the control plane (never on the container host)
4. Injected as environment variables into the container spec
5. Container starts — secrets already present as env vars
6. Plaintext exists only in memory, for the lifetime of the process
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application code reads &lt;code&gt;process.env.DATABASE_URL&lt;/code&gt; exactly as it always has. Zero changes to application code. Zero additional SDK imports. Zero IAM role configuration.&lt;/p&gt;

&lt;p&gt;This is what NEXUS AI calls &lt;strong&gt;Secure Configuration Injection&lt;/strong&gt; — vault-backed runtime config by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  Access Tokens
&lt;/h2&gt;

&lt;p&gt;Secrets protect your application's config. Access Tokens protect access to NEXUS AI itself.&lt;/p&gt;

&lt;p&gt;An Access Token is a scoped credential that authenticates API calls to NEXUS AI — including calls from the CLI, CI/CD pipelines, external scripts, or AI agents running via MCP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token anatomy
&lt;/h3&gt;

&lt;p&gt;Every NEXUS AI Access Token carries three pieces of information:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;token_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stable identifier. Visible in audit logs. Safe to display.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;token_value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The actual secret. Shown once at creation. Never stored in plaintext.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scopes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What the token is allowed to do. Read-only? Deploy-only? Full control?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Tokens are hashed with SHA-256 before storage. If an attacker gets your database, they get hashes — not tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a token
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CLI&lt;/span&gt;
nexus token create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"ci-deploy-prod"&lt;/span&gt; &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write,secrets:read

&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;# Token ID:    tok_01HX9...&lt;/span&gt;
&lt;span class="c"&gt;# Token value: nxt_live_...  ← shown once, copy it now&lt;/span&gt;
&lt;span class="c"&gt;# Scopes:      deploy:write, secrets:read&lt;/span&gt;
&lt;span class="c"&gt;# Expires:     never (set --expires 90d to add expiry)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Or via the NEXUS AI dashboard:&lt;/span&gt;
&lt;span class="c"&gt;# Settings → Access Tokens → New Token&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For CI/CD pipelines, store the token value as a repository secret in your provider (GitHub Actions, GitLab CI, etc.) and inject it as &lt;code&gt;NEXUS_API_KEY&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token scopes
&lt;/h3&gt;

&lt;p&gt;NEXUS AI uses a least-privilege scope model. Grant exactly what the caller needs — nothing more.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;What it allows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deploy:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View deployment status, logs, metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deploy:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create, redeploy, rollback, stop deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;secrets:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List secret names (never values)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;secrets:write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create, update, delete secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;billing:read&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View usage and invoices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full organization access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A CI/CD pipeline that only needs to redeploy on merge gets &lt;code&gt;deploy:write&lt;/code&gt;. It cannot read secrets, cannot view billing, cannot create new deployments from scratch. One compromised pipeline token does not become a full organization breach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token expiry and rotation
&lt;/h3&gt;

&lt;p&gt;Short-lived tokens are better tokens. Set expiry explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus token create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"github-actions-main"&lt;/span&gt; &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write &lt;span class="nt"&gt;--expires&lt;/span&gt; 90d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rotate before expiry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus token rotate tok_01HX9...
&lt;span class="c"&gt;# Old token: revoked immediately&lt;/span&gt;
&lt;span class="c"&gt;# New token: nxt_live_...  ← 90-day window restarts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rotation is zero-downtime. The old token stays valid for a 5-minute grace window — long enough for an in-flight deploy to complete, short enough that a leaked token has minimal exposure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secrets + Tokens in a real pipeline
&lt;/h2&gt;

&lt;p&gt;Here's what a production-grade deploy pipeline looks like with NEXUS AI:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Store secrets once
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Done once, by a developer with secrets:write scope&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;DATABASE_URL &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DATABASE_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;REDIS_URL &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REDIS_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;JWT_SECRET &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;openssl rand &lt;span class="nt"&gt;-hex&lt;/span&gt; 32&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create a scoped CI token
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a deploy-only token for GitHub Actions&lt;/span&gt;
nexus token create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"github-actions-main"&lt;/span&gt; &lt;span class="nt"&gt;--scopes&lt;/span&gt; deploy:write &lt;span class="nt"&gt;--expires&lt;/span&gt; 90d
&lt;span class="c"&gt;# → Store the token value in GitHub Actions secrets as NEXUS_API_KEY&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: CI/CD pipeline (GitHub Actions example)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to NEXUS AI&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NEXUS_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NEXUS_API_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npx nexus-cli deploy redeploy --deployment api-prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No secrets in the pipeline YAML. No secrets in the container image. The pipeline token can trigger a redeploy — it cannot read &lt;code&gt;DATABASE_URL&lt;/code&gt;, cannot change secrets, cannot touch other projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Runtime
&lt;/h3&gt;

&lt;p&gt;When the container starts, it finds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres://...&lt;/span&gt;
&lt;span class="py"&gt;REDIS_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;redis://...&lt;/span&gt;
&lt;span class="py"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ready. No SDK. No fetch-on-startup. No cold-start latency penalty from secret retrieval.&lt;/p&gt;




&lt;h2&gt;
  
  
  RBAC and the audit trail
&lt;/h2&gt;

&lt;p&gt;Access Tokens operate within NEXUS AI's Role-Based Access Control (RBAC) system. Every token is issued to an organization member with a role:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;What they can do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Viewer&lt;/td&gt;
&lt;td&gt;Read logs, status, and deployment metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer&lt;/td&gt;
&lt;td&gt;Deploy, redeploy, rollback; read secret names&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Admin&lt;/td&gt;
&lt;td&gt;Full control including secrets, tokens, and billing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Owner&lt;/td&gt;
&lt;td&gt;Everything Admin can do + delete the organization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code&gt;Developer&lt;/code&gt; role member creating a token cannot grant that token &lt;code&gt;admin&lt;/code&gt; scope. Privilege escalation via token creation is blocked at the model layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The audit log
&lt;/h3&gt;

&lt;p&gt;Every secret operation and token use is recorded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"secret.updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saif@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DATABASE_URL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deployment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-21T09:14:22Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.45"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deploy.redeploy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"actor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tok_01HX9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deployment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-21T09:17:05Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"140.82.114.3"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a deploy fires at 3 AM, you know it was the CI token. When a secret changes, you know who changed it and from where. Audit logs are append-only, exported to your observability stack, and retained for 90 days on Pro and indefinitely on Enterprise.&lt;/p&gt;




&lt;h2&gt;
  
  
  MCP: AI agents and your secrets vault
&lt;/h2&gt;

&lt;p&gt;NEXUS AI ships 37 MCP tools for Claude and other AI agents. When an AI agent uses a token to call the NEXUS AI MCP server, it operates under the same scope model as a human caller.&lt;/p&gt;

&lt;p&gt;An agent with &lt;code&gt;deploy:read&lt;/code&gt; can inspect deployment status and fetch logs. It cannot modify secrets, redeploy, or rollback — unless its token includes &lt;code&gt;deploy:write&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Agent calls nexusai_deploy_status → allowed (deploy:read)&lt;/span&gt;
&lt;span class="c"&gt;# Agent calls nexusai_secrets_create → blocked (secrets:write not granted)&lt;/span&gt;
&lt;span class="c"&gt;# Agent calls nexusai_deploy_redeploy → blocked (deploy:write not granted)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means you can give Claude read-only access to your production environment for diagnosis — and be certain it cannot modify anything. When you want Claude to act (redeploy, rollback), you issue a &lt;code&gt;deploy:write&lt;/code&gt; token explicitly, scoped to exactly that.&lt;/p&gt;

&lt;p&gt;AI agents with unconstrained production access are a liability. Scoped tokens make AI-assisted operations safe by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checklist: zero-plaintext secrets in 10 minutes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Store all secrets with &lt;code&gt;nexus secret set&lt;/code&gt; — delete any existing &lt;code&gt;.env&lt;/code&gt; from your repo&lt;/li&gt;
&lt;li&gt;[ ] Create deployment-scoped tokens for every CI/CD pipeline — one token per pipeline&lt;/li&gt;
&lt;li&gt;[ ] Set token expiry to 90 days maximum — calendar reminders for rotation&lt;/li&gt;
&lt;li&gt;[ ] Assign team members the minimum role they need — Viewers don't need Developer&lt;/li&gt;
&lt;li&gt;[ ] Enable audit log export to your SIEM or logging stack (Datadog, Grafana, etc.)&lt;/li&gt;
&lt;li&gt;[ ] Run &lt;code&gt;nexus secret list&lt;/code&gt; quarterly — delete secrets that no longer have a deployment&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I view a secret value after I've stored it?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No. The vault stores only the encrypted ciphertext. The plaintext value is shown once at creation. This is intentional — if you need to verify a secret, rotate it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to secrets if I delete a deployment?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Secrets are scoped to a deployment. Deleting the deployment marks its secrets as orphaned. Orphaned secrets are purged automatically after 30 days, or immediately if you run &lt;code&gt;nexus secret purge --deployment &amp;lt;name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I handle secrets that multiple deployments share?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Set the secret on each deployment. NEXUS AI does not support cross-deployment secret references by design — shared access is shared blast radius. Duplication is cheaper than a cross-project breach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a Developer-role member read secret values?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No. &lt;code&gt;secrets:read&lt;/code&gt; scope lists secret names (e.g., &lt;code&gt;DATABASE_URL&lt;/code&gt;) but never values. Only the NEXUS AI control plane decrypts values — and only at deploy time, into the container environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What encryption key does NEXUS AI use?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
On NEXUS AI-managed infrastructure, the encryption key is managed by the platform and rotated automatically. On Enterprise On-Prem, you supply &lt;code&gt;SECRETS_ENCRYPTION_KEY&lt;/code&gt; and own the key lifecycle entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use NEXUS AI secrets with a non-NEXUS AI host?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Not directly. The vault is tightly integrated with the deployment runtime. If you're running on external infrastructure, use your cloud provider's native secret manager and inject credentials at the infrastructure level.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Secrets Vault and Access Tokens ship on every NEXUS AI plan — including Starter at $29/mo. No additional configuration, no third-party integrations, no IAM policy documents.&lt;/p&gt;

&lt;p&gt;If you're on an Enterprise or regulated workload, RBAC, audit log retention, and on-prem key management are available on Enterprise and Enterprise On-Prem tiers. Talk to the team at &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;nexusai.run&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How NEXUS AI deploys your app in under 5 minutes&lt;/li&gt;
&lt;li&gt;RBAC deep dive: roles, scopes, and least privilege&lt;/li&gt;
&lt;li&gt;MCP integration: 37 tools for Claude and AI agents&lt;/li&gt;
&lt;li&gt;Audit logs and compliance: what gets recorded and why&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Ship what matters. Lock down the rest.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>security</category>
    </item>
    <item>
      <title>NEXUS AI Audit</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sat, 25 Apr 2026 21:45:13 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/nexus-ai-audit-3n58</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/nexus-ai-audit-3n58</guid>
      <description>&lt;h1&gt;
  
  
  Audit logs and compliance: what gets recorded and why
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; April 21, 2026&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Category:&lt;/strong&gt; Security · Compliance&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reading time:&lt;/strong&gt; 15 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Author:&lt;/strong&gt; NEXUS AI Team&lt;/p&gt;



&lt;p&gt;A production incident happens at 2:47 AM. You wake up to alerts. By the time you open your laptop, the question isn't "what failed" — your monitoring already told you that. The question is "who changed what, when, and from where?"&lt;/p&gt;

&lt;p&gt;Without audit logs, that question takes hours. With audit logs, it takes minutes.&lt;/p&gt;

&lt;p&gt;NEXUS AI records 42 distinct event types across 7 categories — every authentication attempt, every secret operation, every deployment action, every permission change. This post covers exactly what gets recorded, what each severity level means, how retention works, and how the audit log maps to the compliance controls your team, auditors, and regulators care about.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why audit logs exist — and why most teams underinvest in them
&lt;/h2&gt;

&lt;p&gt;Audit logs are not a debugging tool. They are an accountability system.&lt;/p&gt;

&lt;p&gt;The difference matters. A debugging tool helps you understand why software broke. An accountability system answers a harder set of questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did an authorized person take this action?&lt;/li&gt;
&lt;li&gt;From a recognized location?&lt;/li&gt;
&lt;li&gt;At a time that makes sense?&lt;/li&gt;
&lt;li&gt;On the resource they were supposed to touch?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the questions a security incident forces you to answer — and the questions compliance auditors ask during a review. Every minute you spend reconstructing context from application logs and git history is a minute your accountability system didn't pay for itself.&lt;/p&gt;

&lt;p&gt;NEXUS AI's audit log is designed to answer accountability questions in seconds, not hours.&lt;/p&gt;


&lt;h2&gt;
  
  
  The event catalog: 42 event types, 7 categories
&lt;/h2&gt;

&lt;p&gt;Every event stored in the audit log has a named type. Here is the complete catalog.&lt;/p&gt;
&lt;h3&gt;
  
  
  Authentication events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOGIN_SUCCESS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Successful sign-in via password or OAuth&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOGIN_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Failed sign-in attempt (wrong password, invalid token)&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOGOUT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Explicit sign-out&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REGISTER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New account created&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TOKEN_REFRESH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Session token refreshed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TOKEN_EXPIRED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Session token expired and was rejected&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Authentication events are the first line of accountability. A single &lt;code&gt;LOGIN_FAILED&lt;/code&gt; is noise. Fifteen &lt;code&gt;LOGIN_FAILED&lt;/code&gt; events from the same IP in 90 seconds is a brute-force signal — recorded, flagged, and available for your SIEM in real time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deployment events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_CREATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New deployment provisioned&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_UPDATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment configuration changed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_STARTED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stopped deployment brought back online&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_STOPPED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Running deployment halted&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_DELETED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment permanently removed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build or container start failed&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DEPLOYMENT_SCALED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Replica count changed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every deploy action is tied to the actor who triggered it — a user email, a token ID, or both. When a deploy fires at 3 AM, you know whether it was a CI token, a scheduled job, or a human who shouldn't have been working at 3 AM.&lt;/p&gt;
&lt;h3&gt;
  
  
  Security events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DOCKERFILE_VALIDATION_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Submitted Dockerfile failed safety checks&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RATE_LIMIT_EXCEEDED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;API caller exceeded request rate limits&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UNAUTHORIZED_ACCESS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Request rejected due to insufficient permissions&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SUSPICIOUS_ACTIVITY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Behavioral anomaly detected by the security monitor&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CONTAINER_ESCAPE_ATTEMPT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Container process attempted to break isolation&lt;/td&gt;
&lt;td&gt;CRITICAL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;SUSPICIOUS_ACTIVITY&lt;/code&gt; and &lt;code&gt;CONTAINER_ESCAPE_ATTEMPT&lt;/code&gt; are the two events that trigger an immediate alert. They are never demoted to WARNING or lower.&lt;/p&gt;
&lt;h3&gt;
  
  
  Resource events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RESOURCE_LIMIT_EXCEEDED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment exceeded its CPU, memory, or storage limit&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HIGH_CPU_USAGE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Container CPU usage crossed threshold&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HIGH_MEMORY_USAGE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Container memory usage crossed threshold&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Resource events are included in the audit log — not just the metrics system — because they tell the story of capacity-related incidents. A deployment that gets quietly OOM-killed at 4 PM on a Tuesday has a paper trail.&lt;/p&gt;
&lt;h3&gt;
  
  
  Administrative events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;USER_CREATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New team member account created or invited&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;USER_DELETED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Team member removed from the organization&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PERMISSION_CHANGED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Role or scope assignment changed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CONFIG_CHANGED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Organization-level configuration updated&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Administrative events answer the access-review question: not just who has access now, but who granted it, when, and to whom. Every &lt;code&gt;PERMISSION_CHANGED&lt;/code&gt; event records the before and after state in the &lt;code&gt;details&lt;/code&gt; JSON field.&lt;/p&gt;
&lt;h3&gt;
  
  
  Project events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PROJECT_CREATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New project created&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PROJECT_UPDATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Project metadata or settings changed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PROJECT_DELETED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Project and all its deployments deleted&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Secret and vault events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_CREATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New secret stored in the vault&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_UPDATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret value changed&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_ROTATED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret rotated (new value, same name)&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_DELETED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret removed from the vault&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_REVEALED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret value decrypted for display&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_LISTED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret names listed (values not returned)&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECRET_RUNTIME_ACCESSED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Secret decrypted for container injection at deploy time&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;SECRET_REVEALED&lt;/code&gt; is marked WARNING by design. The vault never returns plaintext values through normal operations — if a &lt;code&gt;SECRET_REVEALED&lt;/code&gt; event fires, an admin explicitly requested a value display. That is worth noting.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SECRET_RUNTIME_ACCESSED&lt;/code&gt; records every time a secret is decrypted for injection into a running container. On a high-frequency redeploy environment, this creates a complete timeline of which secrets were active in which container instances.&lt;/p&gt;
&lt;h3&gt;
  
  
  Database intelligence events
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;What triggered it&lt;/th&gt;
&lt;th&gt;Default severity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DATABASE_ACCESSED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;External database connection established&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DATABASE_MODIFIED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Schema change or DDL applied to external database&lt;/td&gt;
&lt;td&gt;WARNING&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DATABASE_QUERY_EXECUTED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SQL query executed against an external database source&lt;/td&gt;
&lt;td&gt;INFO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;DATABASE_MODIFIED&lt;/code&gt; is promoted to WARNING because schema changes are high-impact and difficult to reverse. Every DDL statement executed through NEXUS AI's Database Intelligence layer — whether applied directly or via a proposed fix — produces a record.&lt;/p&gt;


&lt;h2&gt;
  
  
  The audit log record
&lt;/h2&gt;

&lt;p&gt;Every event writes a single record to the &lt;code&gt;audit_logs&lt;/code&gt; table. Here is what that record looks like in full:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f3c8a21b-4d9e-4a7f-b6c1-e2d8f0a3b591"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DEPLOYMENT_CREATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INFO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"usr_01HX9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"organizationId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"org_01HX9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ipAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"140.82.114.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userAgent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nexusapp-cli/2.0.0 node/20.11.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resourceId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dep_api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deployment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DEPLOYMENT_CREATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploymentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ghcr.io/org/api:sha-abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS_APP_RUNNER"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tokenId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tok_01HX9..."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"errorMessage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-21T09:17:05.000Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every field is intentional:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Why it exists&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unique record identifier — stable reference for incident tickets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eventType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Machine-readable event name — filterable, indexable, SIEM-parseable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;severity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;INFO / WARNING / ERROR / CRITICAL — drives alerting and dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;userId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The human actor (null if action was taken by a token with no session)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;organizationId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tenant boundary — logs are always org-scoped; cross-tenant reads are impossible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ipAddress&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Source IP of the request — critical for geolocation anomaly detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;userAgent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CLI version, browser, SDK — surfaces automation vs. human access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resourceId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The specific resource acted upon — deployments, secrets, users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;resourceType&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of resource — enables filtering by type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;action&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Human-readable description of what happened&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;details&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Freeform JSON — event-specific context (image tag, region, old role, new role)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;success&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the action completed successfully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;errorMessage&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If &lt;code&gt;success&lt;/code&gt; is false, why it failed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timestamp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;UTC timestamp of the event — stored with millisecond precision&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;details&lt;/code&gt; field is where event-specific context lives. A &lt;code&gt;PERMISSION_CHANGED&lt;/code&gt; record includes the old role and new role. A &lt;code&gt;SECRET_RUNTIME_ACCESSED&lt;/code&gt; record includes the deployment ID and the name (not value) of the secret. A &lt;code&gt;LOGIN_FAILED&lt;/code&gt; record includes the email attempted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Severity levels
&lt;/h2&gt;

&lt;p&gt;NEXUS AI uses four severity levels. They control how an event is stored, surfaced, and retained.&lt;/p&gt;

&lt;h3&gt;
  
  
  INFO
&lt;/h3&gt;

&lt;p&gt;Normal system operation. Every successful deploy, login, and secret list operation lands here. INFO events are written to the database and available for query, but they do not trigger any alert. They form the baseline — the record of what "normal" looks like.&lt;/p&gt;

&lt;h3&gt;
  
  
  WARNING
&lt;/h3&gt;

&lt;p&gt;Something worth noting. Failed logins, rate limit hits, secret reveal operations, and Dockerfile validation failures are WARNING events. They do not indicate a breach, but they indicate conditions that — in volume or combination — warrant investigation. Five &lt;code&gt;LOGIN_FAILED&lt;/code&gt; events is noise. Fifty in ten minutes is a pattern your SIEM should surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  ERROR
&lt;/h3&gt;

&lt;p&gt;An action failed in a way that requires attention. &lt;code&gt;DEPLOYMENT_FAILED&lt;/code&gt; is an ERROR. These events are logged to the application error stream in addition to the database, so they appear in your observability pipeline immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  CRITICAL
&lt;/h3&gt;

&lt;p&gt;Immediate action required. Only two event types default to CRITICAL: &lt;code&gt;SUSPICIOUS_ACTIVITY&lt;/code&gt; and &lt;code&gt;CONTAINER_ESCAPE_ATTEMPT&lt;/code&gt;. CRITICAL events trigger the alerting pipeline — currently logging to the critical error stream, with email, Slack, and PagerDuty integrations on the roadmap. CRITICAL events are also exempt from the standard 90-day retention purge. They are kept indefinitely, regardless of plan.&lt;/p&gt;




&lt;h2&gt;
  
  
  The security score
&lt;/h2&gt;

&lt;p&gt;NEXUS AI's security monitor computes a rolling 100-point security score for each organization, recalculated across a configurable window (default: 7 days).&lt;/p&gt;

&lt;p&gt;The score starts at 100 and deducts based on event volume:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event category&lt;/th&gt;
&lt;th&gt;Deduction per occurrence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Failed login (&lt;code&gt;LOGIN_FAILED&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;−2 points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limit exceeded (&lt;code&gt;RATE_LIMIT_EXCEEDED&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;−1 point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dockerfile validation failure (&lt;code&gt;DOCKERFILE_VALIDATION_FAILED&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;−5 points&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Critical security event (&lt;code&gt;severity: CRITICAL&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;−10 points&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A score of 100 means no adverse events in the review window. A score of 60 means something is worth investigating. A score below 40 should trigger an active security review.&lt;/p&gt;

&lt;p&gt;The score is visible in the NEXUS AI dashboard under Settings → Security and is available via the API at &lt;code&gt;GET /api/audit/security-summary&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Retention policy
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Retention window&lt;/th&gt;
&lt;th&gt;CRITICAL event retention&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Starter&lt;/td&gt;
&lt;td&gt;90 days&lt;/td&gt;
&lt;td&gt;Indefinite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;90 days&lt;/td&gt;
&lt;td&gt;Indefinite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise&lt;/td&gt;
&lt;td&gt;Configurable (env: &lt;code&gt;AUDIT_LOG_RETENTION_DAYS&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Indefinite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise On-Prem&lt;/td&gt;
&lt;td&gt;You own the database&lt;/td&gt;
&lt;td&gt;You own the database&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The retention job runs daily at 3:30 AM UTC. It purges records older than the retention window — except CRITICAL events, which are never automatically purged.&lt;/p&gt;

&lt;p&gt;On Enterprise, set &lt;code&gt;AUDIT_LOG_RETENTION_DAYS&lt;/code&gt; to any positive integer. Regulated industries typically set this to 365 (HIPAA minimum) or 2555 (7-year financial records requirement).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Example: 365-day retention for HIPAA workloads&lt;/span&gt;
&lt;span class="nv"&gt;AUDIT_LOG_RETENTION_DAYS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;365
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Enterprise On-Prem, you bring your own PostgreSQL cluster. Audit logs live in your database, under your retention and backup policies, with no data leaving your infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Accessing your audit logs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dashboard
&lt;/h3&gt;

&lt;p&gt;The audit log viewer is at Settings → Audit Logs in the NEXUS AI dashboard. Filter by event type, severity, date range, and user. Paginated, searchable, exportable.&lt;/p&gt;

&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;p&gt;The audit log API is at &lt;code&gt;/api/audit/logs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Get the last 50 logs&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?limit=50"&lt;/span&gt;

&lt;span class="c"&gt;# Filter by event type&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?eventType=SECRET_UPDATED&amp;amp;limit=100"&lt;/span&gt;

&lt;span class="c"&gt;# Filter by severity&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?severity=WARNING&amp;amp;limit=100"&lt;/span&gt;

&lt;span class="c"&gt;# Date range (ISO 8601)&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?startDate=2026-04-01T00:00:00Z&amp;amp;endDate=2026-04-21T23:59:59Z"&lt;/span&gt;

&lt;span class="c"&gt;# Security summary for the last 7 days&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/security-summary?days=7"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CSV export
&lt;/h3&gt;

&lt;p&gt;Export up to 10,000 log records as a CSV file — ready to upload to your SIEM, compliance platform, or auditor portal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Export last 30 days to CSV&lt;/span&gt;
curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/export?startDate=2026-03-21T00:00:00Z"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; audit-logs-march-2026.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CSV includes all fields: timestamp, event type, severity, user ID, IP address, action, success, error message, resource ID, and resource type. The &lt;code&gt;details&lt;/code&gt; JSON field is serialized as a string in the CSV export.&lt;/p&gt;

&lt;h3&gt;
  
  
  Available filter endpoints
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/audit/logs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Query logs with filters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/audit/export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Download CSV (up to 10,000 records)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/audit/security-summary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7-day security summary and score&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/audit/security-metrics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Real-time threat metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/audit/event-types&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all 42 event types and 4 severity levels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /api/audit/user-activity/:userId&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;30-day activity summary for a specific user&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Audit logs in a real incident
&lt;/h2&gt;

&lt;p&gt;Here is how audit logs actually look during an incident response workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; At 11:42 PM, a production deployment stops unexpectedly. The on-call engineer opens the audit log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Filter for recent deployment events on the affected resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?eventType=DEPLOYMENT_STOPPED&amp;amp;limit=10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DEPLOYMENT_STOPPED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INFO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tokenId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tok_01HX9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploymentName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"triggeredBy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"access_token"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ipAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"198.51.100.22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-21T23:42:17.000Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;userId&lt;/code&gt; — the stop was triggered by an Access Token, not a human session. &lt;code&gt;tokenId&lt;/code&gt; identifies which token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Cross-reference the token ID against the token list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus token list &lt;span class="nt"&gt;--json&lt;/span&gt; | jq &lt;span class="s1"&gt;'.[] | select(.id == "tok_01HX9...")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; The token was named &lt;code&gt;github-actions-prod&lt;/code&gt;. It has &lt;code&gt;deploy:write&lt;/code&gt; scope. But the GitHub Actions workflow that uses it is only supposed to trigger redeployments, not stops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Pull the full recent activity for that token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?limit=20"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  jq &lt;span class="s1"&gt;'.data.logs[] | select(.details.tokenId == "tok_01HX9...")'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; The token was used from IP &lt;code&gt;198.51.100.22&lt;/code&gt;. Your CI/CD pipeline runs from &lt;code&gt;140.82.114.0/24&lt;/code&gt;. This IP is outside that range.&lt;/p&gt;

&lt;p&gt;The token was compromised. You revoke it immediately, rotate secrets, and have a complete timeline of every action it took — from the first legitimate use to the unauthorized stop. The entire investigation took 11 minutes.&lt;/p&gt;

&lt;p&gt;Without audit logs: that same investigation would have required GitHub Actions logs, cloud provider logs, and a manual timeline reconstruction. Best case: 90 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Compliance mapping
&lt;/h2&gt;

&lt;p&gt;NEXUS AI's audit log maps directly to the access-control and audit requirements in the major compliance frameworks. This is not a marketing table — these are the specific control IDs your auditor will check.&lt;/p&gt;

&lt;h3&gt;
  
  
  HIPAA
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HIPAA requirement&lt;/th&gt;
&lt;th&gt;Control ID&lt;/th&gt;
&lt;th&gt;NEXUS AI coverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Access control — unique user identification&lt;/td&gt;
&lt;td&gt;§164.312(a)(2)(i)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;userId&lt;/code&gt; on every record; token-based access uses &lt;code&gt;tokenId&lt;/code&gt; in &lt;code&gt;details&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit controls — hardware, software, procedural mechanisms&lt;/td&gt;
&lt;td&gt;§164.312(b)&lt;/td&gt;
&lt;td&gt;42 event types, append-only log, 90–365 day retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automatic logoff — session inactivity termination&lt;/td&gt;
&lt;td&gt;§164.312(a)(2)(iii)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;TOKEN_EXPIRED&lt;/code&gt; event records session termination&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption and decryption — PHI protection&lt;/td&gt;
&lt;td&gt;§164.312(a)(2)(iv)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SECRET_RUNTIME_ACCESSED&lt;/code&gt; records every secret decryption event&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Person or entity authentication — verify identity before granting access&lt;/td&gt;
&lt;td&gt;§164.312(d)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;LOGIN_FAILED&lt;/code&gt; events surface failed authentication&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  SOC 2 Type II
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SOC 2 criterion&lt;/th&gt;
&lt;th&gt;Trust Service Criterion&lt;/th&gt;
&lt;th&gt;NEXUS AI coverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Logical access controls&lt;/td&gt;
&lt;td&gt;CC6.1&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PERMISSION_CHANGED&lt;/code&gt;, &lt;code&gt;USER_CREATED&lt;/code&gt;, &lt;code&gt;USER_DELETED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System access authorization&lt;/td&gt;
&lt;td&gt;CC6.2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;LOGIN_SUCCESS&lt;/code&gt;, &lt;code&gt;LOGIN_FAILED&lt;/code&gt;, &lt;code&gt;UNAUTHORIZED_ACCESS&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User registration and de-provisioning&lt;/td&gt;
&lt;td&gt;CC6.3&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;USER_CREATED&lt;/code&gt;, &lt;code&gt;USER_DELETED&lt;/code&gt;, &lt;code&gt;PERMISSION_CHANGED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restricting access to data in transit&lt;/td&gt;
&lt;td&gt;CC6.7&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SECRET_RUNTIME_ACCESSED&lt;/code&gt;, &lt;code&gt;DATABASE_ACCESSED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring of system components&lt;/td&gt;
&lt;td&gt;CC7.2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;HIGH_CPU_USAGE&lt;/code&gt;, &lt;code&gt;HIGH_MEMORY_USAGE&lt;/code&gt;, &lt;code&gt;RESOURCE_LIMIT_EXCEEDED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident detection and reporting&lt;/td&gt;
&lt;td&gt;CC7.3&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;SUSPICIOUS_ACTIVITY&lt;/code&gt;, &lt;code&gt;CONTAINER_ESCAPE_ATTEMPT&lt;/code&gt; (CRITICAL, alerted immediately)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  GDPR
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GDPR requirement&lt;/th&gt;
&lt;th&gt;Article&lt;/th&gt;
&lt;th&gt;NEXUS AI coverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Records of processing activities&lt;/td&gt;
&lt;td&gt;Art. 30&lt;/td&gt;
&lt;td&gt;Complete event log with timestamp, actor, resource, and outcome&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accountability — demonstrate compliance&lt;/td&gt;
&lt;td&gt;Art. 5(2)&lt;/td&gt;
&lt;td&gt;Append-only log with no modification capability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data access requests — who accessed what&lt;/td&gt;
&lt;td&gt;Art. 15&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;user-activity/:userId&lt;/code&gt; endpoint for per-user activity reports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breach notification — detect and respond within 72 hours&lt;/td&gt;
&lt;td&gt;Art. 33&lt;/td&gt;
&lt;td&gt;CRITICAL events alerted immediately; &lt;code&gt;SUSPICIOUS_ACTIVITY&lt;/code&gt; surfaces breach signals&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  PCI DSS (v4.0)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PCI DSS requirement&lt;/th&gt;
&lt;th&gt;Control&lt;/th&gt;
&lt;th&gt;NEXUS AI coverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Track and monitor access to cardholder data&lt;/td&gt;
&lt;td&gt;Req. 10.2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;DATABASE_ACCESSED&lt;/code&gt;, &lt;code&gt;DATABASE_QUERY_EXECUTED&lt;/code&gt; for connected payment databases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Record user access to audit trails&lt;/td&gt;
&lt;td&gt;Req. 10.2.1&lt;/td&gt;
&lt;td&gt;All 42 event types record &lt;code&gt;userId&lt;/code&gt; or &lt;code&gt;tokenId&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Record privileged access&lt;/td&gt;
&lt;td&gt;Req. 10.2.1.b&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PERMISSION_CHANGED&lt;/code&gt; records role elevations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retain audit log history for at least 12 months&lt;/td&gt;
&lt;td&gt;Req. 10.7&lt;/td&gt;
&lt;td&gt;Set &lt;code&gt;AUDIT_LOG_RETENTION_DAYS=365&lt;/code&gt; on Enterprise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review logs daily&lt;/td&gt;
&lt;td&gt;Req. 10.6&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GET /api/audit/logs&lt;/code&gt; with date filter; exportable to SIEM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Integrating with your SIEM
&lt;/h2&gt;

&lt;p&gt;NEXUS AI does not require a native SIEM integration — the export API and JSON query endpoint are designed to plug into any pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Datadog:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pull last hour of WARNING+ events and ship to Datadog&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$NEXUS_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://nexusai.run/api/audit/logs?severity=WARNING&amp;amp;startDate=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-v-1H&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%dT%H:%M:%SZ'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  jq &lt;span class="s1"&gt;'.data.logs[]'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; event&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://http-intake.logs.datadoghq.com/api/v2/logs"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"DD-API-KEY: &lt;/span&gt;&lt;span class="nv"&gt;$DD_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Grafana / Loki:&lt;/strong&gt; Ship the JSON response from &lt;code&gt;/api/audit/logs&lt;/code&gt; via a log shipper (Promtail, Alloy) configured to poll the endpoint on a scheduled interval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Splunk / SIEM:&lt;/strong&gt; Use the CSV export endpoint (&lt;code&gt;/api/audit/export&lt;/code&gt;) on a scheduled basis and ingest via Splunk's file monitor input.&lt;/p&gt;

&lt;p&gt;On the Enterprise On-Prem plan, audit logs live in your PostgreSQL cluster. Query them directly with any BI or SIEM tool that supports PostgreSQL — no export pipeline required.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the audit log does NOT record
&lt;/h2&gt;

&lt;p&gt;Knowing the boundaries of any control is as important as knowing what it covers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secret values are never logged.&lt;/strong&gt; &lt;code&gt;SECRET_RUNTIME_ACCESSED&lt;/code&gt; records that a secret named &lt;code&gt;DATABASE_URL&lt;/code&gt; was accessed for deployment &lt;code&gt;api-prod&lt;/code&gt;. It does not record the value of &lt;code&gt;DATABASE_URL&lt;/code&gt;. The plaintext never touches the audit log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application-level data is not recorded.&lt;/strong&gt; NEXUS AI audits actions taken on the platform — deployments, secrets, members, tokens. It does not audit what your application does with the resources it receives. If your app logs &lt;code&gt;process.env.DATABASE_URL&lt;/code&gt; at startup, that is an application-level concern, not a platform-level audit event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read operations on deployments are not individually logged.&lt;/strong&gt; Viewing a deployment's status in the dashboard does not produce an audit event. Audit events capture state changes and security-relevant reads (secrets, databases). Routine dashboard reads would generate millions of low-value INFO events per day on active organizations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container stdout/stderr is not the audit log.&lt;/strong&gt; Build logs and runtime logs are separate from the audit log. They are accessible via &lt;code&gt;GET /api/deployments/:id/logs&lt;/code&gt; and stored in the observability layer, not in &lt;code&gt;audit_logs&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checklist: audit log hygiene
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Review &lt;code&gt;GET /api/audit/security-summary&lt;/code&gt; weekly — if the score drops below 80, investigate&lt;/li&gt;
&lt;li&gt;[ ] Set &lt;code&gt;AUDIT_LOG_RETENTION_DAYS=365&lt;/code&gt; for HIPAA, financial, or PCI workloads (Enterprise plan)&lt;/li&gt;
&lt;li&gt;[ ] Export monthly CSVs to your compliance archive before the quarterly close&lt;/li&gt;
&lt;li&gt;[ ] Pull &lt;code&gt;GET /api/audit/user-activity/:userId&lt;/code&gt; for every departing team member as part of offboarding&lt;/li&gt;
&lt;li&gt;[ ] Filter for &lt;code&gt;PERMISSION_CHANGED&lt;/code&gt; events during quarterly access reviews — verify every role change was intentional&lt;/li&gt;
&lt;li&gt;[ ] Confirm no &lt;code&gt;SECRET_REVEALED&lt;/code&gt; events in the last 30 days unless explicitly authorized&lt;/li&gt;
&lt;li&gt;[ ] Set up a SIEM pipeline for &lt;code&gt;severity=WARNING&lt;/code&gt; events if your team size exceeds 10 engineers&lt;/li&gt;
&lt;li&gt;[ ] On Enterprise On-Prem: verify your PostgreSQL backup schedule includes the &lt;code&gt;audit_logs&lt;/code&gt; table&lt;/li&gt;
&lt;li&gt;[ ] Document your retention period in your security policy before your next audit&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I delete an audit log entry?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
No. Audit log records are append-only. There is no API endpoint to delete individual records. The retention job purges records older than the retention window — but only non-CRITICAL events, and only automatically. This immutability is intentional: an audit log you can edit is not an audit log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who can access audit logs?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Audit log access requires the &lt;code&gt;audit.read&lt;/code&gt; org permission, which is granted to OWNER and ADMIN roles. Developer and lower roles cannot query the audit log. This prevents a Developer from inspecting what other users have done — audit visibility is a privilege, not a default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the audit log capture API calls made by NEXUS AI MCP tools (Claude agents)?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. MCP tool calls go through the same API layer as CLI and dashboard actions. They produce audit events with the token ID in &lt;code&gt;details.tokenId&lt;/code&gt; and a &lt;code&gt;userAgent&lt;/code&gt; that identifies the MCP client. You can filter for agent-originated actions by querying for the specific token ID issued to your MCP integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to audit logs if I downgrade my plan?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Logs are not deleted on plan downgrade. If you downgrade from Enterprise (365-day retention) to Pro (90-day retention), the retention job will begin purging records older than 90 days on its next daily run. Export before downgrading if you need records beyond the 90-day window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the audit log encrypted at rest?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. The &lt;code&gt;audit_logs&lt;/code&gt; table lives in the same PostgreSQL database as the rest of your organization's data. The database is encrypted at rest using AES-256. On Enterprise On-Prem, encryption at rest is your infrastructure team's responsibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I receive real-time alerts for specific event types?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
CRITICAL events (SUSPICIOUS_ACTIVITY, CONTAINER_ESCAPE_ATTEMPT) trigger the alert pipeline immediately. For custom alerting on other event types — for example, an alert any time &lt;code&gt;PERMISSION_CHANGED&lt;/code&gt; fires — the current path is to poll &lt;code&gt;/api/audit/logs&lt;/code&gt; via your SIEM and configure alert rules there. Native webhook delivery for specific event types is on the product roadmap.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The audit log is available on every NEXUS AI plan, including Starter at $29/mo. The 90-day retention window, CSV export, and full API access ship on all plans. Configurable retention windows (&lt;code&gt;AUDIT_LOG_RETENTION_DAYS&lt;/code&gt;) and indefinite CRITICAL event retention are available on Enterprise and Enterprise On-Prem.&lt;/p&gt;

&lt;p&gt;If you are working through a HIPAA Business Associate Agreement, SOC 2 audit, or PCI self-assessment questionnaire, the compliance table in this post maps directly to the evidence your auditor needs. The CSV export at &lt;code&gt;/api/audit/export&lt;/code&gt; is the artifact.&lt;/p&gt;

&lt;p&gt;For regulated workloads, healthcare data, or financial applications, the Enterprise plan adds configurable retention, dedicated security review, and SAML SSO. Reach out at &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;nexusai.run&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop shipping secrets. Start using a vault.&lt;/li&gt;
&lt;li&gt;RBAC deep dive: roles, scopes, and least privilege&lt;/li&gt;
&lt;li&gt;MCP integration: 37 tools for Claude and AI agents&lt;/li&gt;
&lt;li&gt;How NEXUS AI deploys your app in under 5 minutes&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;What you can't see, you can't defend. What you can't prove, you can't audit.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Serverless deployment with NEXUS AI</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sat, 25 Apr 2026 21:42:10 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/serverless-deployment-with-nexus-ai-l6c</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/serverless-deployment-with-nexus-ai-l6c</guid>
      <description>&lt;h1&gt;
  
  
  Serverless deployment with NEXUS AI: custom domains, scaling, rollback, and more
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; April 25, 2026&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Category:&lt;/strong&gt; Platform · DevOps&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reading time:&lt;/strong&gt; 16 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Author:&lt;/strong&gt; NEXUS AI Team&lt;/p&gt;



&lt;p&gt;Serverless means different things to different teams. For most, it means: don't manage servers, don't think about capacity until it matters, and pay for what you actually run. That premise is right. The implementation — tangled cloud console configurations, provider-specific YAML, and per-cloud IAM policies — is where the promise breaks down.&lt;/p&gt;

&lt;p&gt;NEXUS AI deploys containerized applications to AWS App Runner, Google Cloud Run, and Azure Container Apps from a single CLI command. No cloud console. No provider-specific configuration files. Custom domains, replica scaling, one-click rollback, and health checks work the same way across all three.&lt;/p&gt;

&lt;p&gt;This post covers every production feature in detail: how it works, what it costs, and the exact CLI commands to run it.&lt;/p&gt;


&lt;h2&gt;
  
  
  How NEXUS AI serverless works
&lt;/h2&gt;

&lt;p&gt;NEXUS AI acts as a deployment orchestration layer on top of the three major serverless container runtimes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Runtime&lt;/th&gt;
&lt;th&gt;What runs your container&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GCP_CLOUD_RUN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Google Cloud Run&lt;/td&gt;
&lt;td&gt;Google's fully managed serverless container platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AWS_APP_RUNNER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AWS App Runner&lt;/td&gt;
&lt;td&gt;AWS's fully managed container runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AZURE_CONTAINER_APPS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Azure Container Apps&lt;/td&gt;
&lt;td&gt;Azure's serverless container service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LOCAL_DOCKER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NEXUS AI managed&lt;/td&gt;
&lt;td&gt;NEXUS AI's own managed Docker infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You choose the provider at deploy time. NEXUS AI handles the cloud-side provisioning — service creation, IAM, registry, networking — and gives you a live URL within minutes. Switching providers is a single flag change on the next redeploy.&lt;/p&gt;

&lt;p&gt;Your container runs on your cloud account (Pro and above), not on shared NEXUS AI infrastructure. The data and workload stay in your AWS, Google Cloud, or Azure environment.&lt;/p&gt;


&lt;h2&gt;
  
  
  Your first serverless deployment
&lt;/h2&gt;

&lt;p&gt;Deploy from a Git repository in one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; api-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/your-org/your-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--branch&lt;/span&gt; main &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; GCP_CLOUD_RUN &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-central1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or deploy a pre-built container image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; api-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt; ghcr.io/your-org/api:latest &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; AWS_APP_RUNNER &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within 3–5 minutes, your deployment is live at a &lt;code&gt;*.nexusai.run&lt;/code&gt; subdomain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Deployment api-prod created
  URL:      https://api-prod.nexusai.run
  Provider: AWS_APP_RUNNER (us-east-1)
  Status:   RUNNING
  Replicas: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Dockerfile required if you deploy from source — NEXUS AI detects your runtime and generates one. No registry setup, no IAM policy documents, no VPC configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environments
&lt;/h2&gt;

&lt;p&gt;Every deployment belongs to an environment: &lt;code&gt;DEVELOPMENT&lt;/code&gt;, &lt;code&gt;STAGING&lt;/code&gt;, or &lt;code&gt;PRODUCTION&lt;/code&gt;. Environments affect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which secrets are injected (secrets are scoped per environment)&lt;/li&gt;
&lt;li&gt;Which team members can deploy (RBAC enforces environment-level permissions)&lt;/li&gt;
&lt;li&gt;Which providers are available (controlled by your org's provider config)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Deploy the same app to staging and production as separate deployments&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; api-staging &lt;span class="nt"&gt;--env&lt;/span&gt; staging &lt;span class="nt"&gt;--provider&lt;/span&gt; GCP_CLOUD_RUN ...
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; api-prod    &lt;span class="nt"&gt;--env&lt;/span&gt; production &lt;span class="nt"&gt;--provider&lt;/span&gt; AWS_APP_RUNNER ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Staging and production run independently — different secrets, different provider configs, same codebase. A bad deploy to staging never touches production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Custom domains
&lt;/h2&gt;

&lt;p&gt;Every deployment gets a &lt;code&gt;*.nexusai.run&lt;/code&gt; subdomain automatically. For production workloads, attach your own domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a custom domain
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus domain add api-prod app.yourcompany.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ Domain app.yourcompany.com added to api-prod
  Verification: PENDING

  Add this DNS record at your registrar:

  Type:  CNAME
  Name:  app
  Value: api-prod.nexusai.run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify DNS
&lt;/h3&gt;

&lt;p&gt;Once you've added the CNAME record at your registrar, trigger verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus domain verify api-prod &amp;lt;domain-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NEXUS AI checks DNS propagation and issues a TLS certificate automatically. Verification typically completes within 2–10 minutes of DNS propagation, which depends on your TTL settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apex domains
&lt;/h3&gt;

&lt;p&gt;Both subdomain (&lt;code&gt;app.yourcompany.com&lt;/code&gt;) and apex (&lt;code&gt;yourcompany.com&lt;/code&gt;) are supported. For apex domains, use your registrar's ALIAS or ANAME record (or CNAME flattening if your registrar supports it) pointing to &lt;code&gt;api-prod.nexusai.run&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  List and remove domains
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List all domains for a deployment&lt;/span&gt;
nexus domain list api-prod

&lt;span class="c"&gt;# Remove a domain&lt;/span&gt;
nexus domain remove api-prod &amp;lt;domain-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom domains are available on Starter ($29/mo) and above. The Free plan uses &lt;code&gt;*.nexusai.run&lt;/code&gt; subdomains only.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scaling
&lt;/h2&gt;

&lt;p&gt;Scale a running deployment between 1 and 10 replicas with a single command. No redeploy required — scaling applies to the live deployment immediately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Scale up before a high-traffic event&lt;/span&gt;
nexus deploy scale api-prod &lt;span class="nt"&gt;--replicas&lt;/span&gt; 5

&lt;span class="c"&gt;# Scale back down after&lt;/span&gt;
nexus deploy scale api-prod &lt;span class="nt"&gt;--replicas&lt;/span&gt; 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ api-prod scaled to 5 replica(s)
  Previous: 2
  Current:  5
  Provider: GCP_CLOUD_RUN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Google Cloud Run, AWS App Runner, and Azure Container Apps, scaling is applied directly to the underlying service — NEXUS AI calls the provider's API to set the replica count and the change takes effect within 30–60 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replica limits
&lt;/h3&gt;

&lt;p&gt;The maximum is 10 replicas per deployment across all plans. For workloads requiring more than 10 replicas, use the provider's native auto-scaling configuration directly on the cloud console alongside NEXUS AI's managed deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling and cost
&lt;/h3&gt;

&lt;p&gt;Replicas run continuously on App Runner and Cloud Run until you scale back down. They are not auto-scaled to zero. If you need scale-to-zero, configure minimum instances on the underlying provider or use the &lt;code&gt;nexus deploy stop&lt;/code&gt; command to halt a deployment entirely during off-hours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop during off-hours&lt;/span&gt;
nexus deploy stop api-staging

&lt;span class="c"&gt;# Restart when needed&lt;/span&gt;
nexus deploy start api-staging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Health checks
&lt;/h2&gt;

&lt;p&gt;NEXUS AI configures health checks on every deployment. A deployment that fails health checks is automatically flagged — and if it stays unhealthy past the retry threshold, it surfaces in both the dashboard and your audit log.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Health checks are configured at deploy time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; api-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--health-check-type&lt;/span&gt; http &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--health-check-url&lt;/span&gt; /health &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--health-check-interval&lt;/span&gt; 30 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--health-check-timeout&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--health-check-retries&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--health-check-start-period&lt;/span&gt; 40 &lt;span class="se"&gt;\&lt;/span&gt;
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--health-check-type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;http&lt;/code&gt;, &lt;code&gt;tcp&lt;/code&gt;, or &lt;code&gt;none&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--health-check-url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Endpoint checked for HTTP type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--health-check-interval&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;30s&lt;/td&gt;
&lt;td&gt;Seconds between checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--health-check-timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3s&lt;/td&gt;
&lt;td&gt;Max wait per check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--health-check-retries&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Failures before marking unhealthy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--health-check-start-period&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;40s&lt;/td&gt;
&lt;td&gt;Grace period before checks begin&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 40-second start period is the most important default to understand. It gives your container time to initialize before health checks begin — a Node.js app loading large models or a Java app with a slow JVM startup won't be marked unhealthy before it's ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check current health status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy status api-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME       STATUS   HEALTH    REPLICAS  RESTARTS  PROVIDER         UPTIME
api-prod   RUNNING  healthy   2         0         AWS_APP_RUNNER   14h ago
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Rollback
&lt;/h2&gt;

&lt;p&gt;Redeploy to a previous known-good state with one command. No rebuilding, no config archaeology.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy rollback api-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rollback is available on &lt;strong&gt;Pro ($149/mo) and above&lt;/strong&gt;. On Free and Starter plans, rollback is not available — the recovery path is a new deployment from the previous image tag or branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  How rollback works
&lt;/h3&gt;

&lt;p&gt;NEXUS AI stores the previous deployment configuration — image, environment variables, secrets references, provider, region, and replica count. When you rollback, it provisions a new deployment using that configuration. The original deployment record is preserved in your history.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check deployment history before rolling back&lt;/span&gt;
nexus deploy list &lt;span class="nt"&gt;--json&lt;/span&gt; | jq &lt;span class="s1"&gt;'.[] | select(.name | startswith("api-prod"))'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-prod"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"FAILED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-25T14:22:00Z"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rollback-k3x9ab2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RUNNING"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-25T14:30:00Z"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rollback deployment gets a generated name (&lt;code&gt;rollback-{timestamp}&lt;/code&gt;) and runs at the same replica count as the original.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secrets and environment variables
&lt;/h2&gt;

&lt;p&gt;Secrets are injected at runtime — never baked into the container image. Set them once; they're available across redeployments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Store secrets in the vault&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;DATABASE_URL &lt;span class="s2"&gt;"postgres://..."&lt;/span&gt; &lt;span class="nt"&gt;--environment&lt;/span&gt; production
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;STRIPE_SECRET_KEY &lt;span class="s2"&gt;"sk_live_..."&lt;/span&gt; &lt;span class="nt"&gt;--environment&lt;/span&gt; production
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;OPENAI_API_KEY &lt;span class="s2"&gt;"sk-..."&lt;/span&gt; &lt;span class="nt"&gt;--environment&lt;/span&gt; production

&lt;span class="c"&gt;# Deploy — secrets are automatically injected&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; api-prod &lt;span class="nt"&gt;--env&lt;/span&gt; production ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application reads them as standard environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No SDK. No fetch-on-startup. No cold-start penalty from secret retrieval. Secrets are decrypted in the NEXUS AI control plane and injected into the container spec before the first process starts.&lt;/p&gt;

&lt;p&gt;Environment variables that aren't secrets can be passed inline at deploy time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; api-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env-var&lt;/span&gt; &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env-var&lt;/span&gt; &lt;span class="nv"&gt;LOG_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--env-var&lt;/span&gt; &lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3000 &lt;span class="se"&gt;\&lt;/span&gt;
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Multi-service deployments
&lt;/h2&gt;

&lt;p&gt;NEXUS AI supports Docker Compose deployments for applications that require multiple services running together — an API, a background worker, and a Redis sidecar, for example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; platform-prod &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/your-org/platform &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--compose&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;--compose&lt;/code&gt; is specified, NEXUS AI reads your &lt;code&gt;docker-compose.yml&lt;/code&gt;, provisions each service as a deployment, and wires them together within the same project. Services can reference each other by name on the internal network.&lt;/p&gt;




&lt;h2&gt;
  
  
  Redeploy
&lt;/h2&gt;

&lt;p&gt;Push a new image or rebuild from source without changing any configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Redeploy from the same source (pulls latest from the branch)&lt;/span&gt;
nexus deploy redeploy api-prod

&lt;span class="c"&gt;# Or from CI/CD using an Access Token&lt;/span&gt;
&lt;span class="nv"&gt;NEXUS_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nxk_... nexus deploy redeploy api-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Redeployments on cloud providers (AWS App Runner, Google Cloud Run, Azure Container Apps) complete in 60–90 seconds. The old revision stays running until the new one passes health checks — zero-downtime by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  CI/CD integration
&lt;/h2&gt;

&lt;p&gt;A typical GitHub Actions pipeline with NEXUS AI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .&lt;/span&gt;
          &lt;span class="s"&gt;docker push ghcr.io/${{ github.repository }}:${{ github.sha }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to NEXUS AI&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NEXUS_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NEXUS_API_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npx nexus-cli deploy redeploy api-prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pipeline token uses &lt;code&gt;deploy:write&lt;/code&gt; scope only — it cannot read secrets, change configuration, or touch other deployments. One compromised pipeline token is one redeployment trigger, nothing more.&lt;/p&gt;




&lt;h2&gt;
  
  
  Auto-destroy
&lt;/h2&gt;

&lt;p&gt;Temporary deployments — review apps, QA environments, demo instances — can be set to self-destruct after a fixed window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Spin up a review deployment that destroys itself after 24 hours&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; pr-1234-review &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--auto-destroy&lt;/span&gt; 24h &lt;span class="se"&gt;\&lt;/span&gt;
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deployment runs normally until the deadline, then stops and cleans up its cloud resources automatically. No manual teardown required, no forgotten review apps billing at end of month.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-time logs
&lt;/h2&gt;

&lt;p&gt;Stream build and runtime logs for any deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Follow runtime logs&lt;/span&gt;
nexus deploy logs api-prod &lt;span class="nt"&gt;--follow&lt;/span&gt;

&lt;span class="c"&gt;# Get last 200 lines&lt;/span&gt;
nexus deploy logs api-prod &lt;span class="nt"&gt;--tail&lt;/span&gt; 200

&lt;span class="c"&gt;# Filter by keyword&lt;/span&gt;
nexus deploy logs api-prod &lt;span class="nt"&gt;--follow&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ERROR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Logs are available within seconds of a container writing to stdout/stderr. Build logs (the image build, Dockerfile execution, dependency installation) are also accessible via the same command with &lt;code&gt;--build&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Plan comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Starter ($29/mo)&lt;/th&gt;
&lt;th&gt;Pro ($149/mo)&lt;/th&gt;
&lt;th&gt;Enterprise&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Deployments&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Providers&lt;/td&gt;
&lt;td&gt;Managed Docker&lt;/td&gt;
&lt;td&gt;Docker + Google Cloud&lt;/td&gt;
&lt;td&gt;All 4 providers&lt;/td&gt;
&lt;td&gt;All 4 providers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom domains&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team members&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI generations/day&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your cloud account&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replica scaling (1–10)&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health checks&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit logs&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Deployment command reference
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Deploy from source&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;name&amp;gt; &lt;span class="nt"&gt;--repo&lt;/span&gt; &amp;lt;url&amp;gt; &lt;span class="nt"&gt;--branch&lt;/span&gt; &amp;lt;branch&amp;gt; &lt;span class="nt"&gt;--provider&lt;/span&gt; &amp;lt;provider&amp;gt; &lt;span class="nt"&gt;--port&lt;/span&gt; &amp;lt;port&amp;gt;

&lt;span class="c"&gt;# Deploy from image&lt;/span&gt;
nexus deploy create &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;name&amp;gt; &lt;span class="nt"&gt;--image&lt;/span&gt; &amp;lt;image&amp;gt; &lt;span class="nt"&gt;--provider&lt;/span&gt; &amp;lt;provider&amp;gt; &lt;span class="nt"&gt;--port&lt;/span&gt; &amp;lt;port&amp;gt;

&lt;span class="c"&gt;# Redeploy (same config, new build)&lt;/span&gt;
nexus deploy redeploy &amp;lt;name&amp;gt;

&lt;span class="c"&gt;# Scale replicas (1–10)&lt;/span&gt;
nexus deploy scale &amp;lt;name&amp;gt; &lt;span class="nt"&gt;--replicas&lt;/span&gt; &amp;lt;n&amp;gt;

&lt;span class="c"&gt;# Rollback to previous version (Pro+)&lt;/span&gt;
nexus deploy rollback &amp;lt;name&amp;gt;

&lt;span class="c"&gt;# Stop / start&lt;/span&gt;
nexus deploy stop &amp;lt;name&amp;gt;
nexus deploy start &amp;lt;name&amp;gt;

&lt;span class="c"&gt;# View status&lt;/span&gt;
nexus deploy status &amp;lt;name&amp;gt;

&lt;span class="c"&gt;# Stream logs&lt;/span&gt;
nexus deploy logs &amp;lt;name&amp;gt; &lt;span class="nt"&gt;--follow&lt;/span&gt;

&lt;span class="c"&gt;# List deployments&lt;/span&gt;
nexus deploy list

&lt;span class="c"&gt;# Delete deployment&lt;/span&gt;
nexus deploy delete &amp;lt;name&amp;gt;

&lt;span class="c"&gt;# Custom domains&lt;/span&gt;
nexus domain add &amp;lt;deployment&amp;gt; &amp;lt;domain&amp;gt;
nexus domain verify &amp;lt;deployment&amp;gt; &amp;lt;domain-id&amp;gt;
nexus domain list &amp;lt;deployment&amp;gt;
nexus domain remove &amp;lt;deployment&amp;gt; &amp;lt;domain-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Checklist: production-ready serverless deployment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Set all secrets via &lt;code&gt;nexus secret set&lt;/code&gt; before first deploy — zero plaintext env vars&lt;/li&gt;
&lt;li&gt;[ ] Configure &lt;code&gt;--health-check-url&lt;/code&gt; to match your app's actual health endpoint&lt;/li&gt;
&lt;li&gt;[ ] Set &lt;code&gt;--health-check-start-period&lt;/code&gt; to at least your app's cold-start time&lt;/li&gt;
&lt;li&gt;[ ] Create a scoped &lt;code&gt;deploy:write&lt;/code&gt; token for CI/CD — never use your personal token in pipelines&lt;/li&gt;
&lt;li&gt;[ ] Add your custom domain and verify DNS before announcing the URL&lt;/li&gt;
&lt;li&gt;[ ] Run &lt;code&gt;nexus deploy status &amp;lt;name&amp;gt; --watch&lt;/code&gt; on the first production deploy to catch health check failures early&lt;/li&gt;
&lt;li&gt;[ ] Set &lt;code&gt;--auto-destroy&lt;/code&gt; on review and QA deployments — prevent billing surprises&lt;/li&gt;
&lt;li&gt;[ ] Scale to at least 2 replicas for production — single-replica deployments have no redundancy&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Which cloud provider should I use?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For most workloads: Google Cloud Run (&lt;code&gt;GCP_CLOUD_RUN&lt;/code&gt;) for its zero-to-running speed and global network, AWS App Runner (&lt;code&gt;AWS_APP_RUNNER&lt;/code&gt;) if your team already runs on AWS and wants everything in one account, Azure Container Apps (&lt;code&gt;AZURE_CONTAINER_APPS&lt;/code&gt;) for Microsoft-stack integrations. All three behave identically from the NEXUS AI CLI perspective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does NEXUS AI support scale-to-zero?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Not natively managed from the CLI — replicas run continuously at whatever count you set. The underlying providers (Cloud Run, Container Apps) support scale-to-zero natively; you can configure it on the cloud console alongside NEXUS AI's deployment. &lt;code&gt;nexus deploy stop&lt;/code&gt; halts the deployment entirely, which achieves zero cost during idle periods for non-production environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I bring my own Dockerfile?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Yes. If your repository includes a &lt;code&gt;Dockerfile&lt;/code&gt;, NEXUS AI uses it. If not, it generates one based on detected runtime (Node.js, Python, Go, Java, etc.). You can also pass a Dockerfile path explicitly with &lt;code&gt;--dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does rollback work on Cloud Run and App Runner?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
NEXUS AI stores your previous deployment configuration and provisions a new deployment from it — it does not use the provider's native revision rollback. This means rollback works identically across all four providers and preserves a clean audit trail of every state the deployment has been in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if a deployment fails health checks?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The deployment status changes to &lt;code&gt;FAILED&lt;/code&gt; or &lt;code&gt;UNHEALTHY&lt;/code&gt;. For cloud providers, the previous revision stays running (Cloud Run and Container Apps keep the last healthy revision active). You'll see a &lt;code&gt;DEPLOYMENT_FAILED&lt;/code&gt; event in your audit log with the exit code and error message. Run &lt;code&gt;nexus deploy logs &amp;lt;name&amp;gt;&lt;/code&gt; to see what went wrong, then redeploy or rollback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run multiple services (API + worker + DB) in one deployment?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Use &lt;code&gt;--compose&lt;/code&gt; to deploy a Docker Compose file. Each service in the compose file becomes a tracked service under the same deployment, connected on an internal network. External database connections should use NEXUS AI secrets rather than running a database container — ephemeral containers are not a reliable database host.&lt;/p&gt;


&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Start with a single command. If your app is already containerized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--image&lt;/span&gt; your-registry/your-app:latest &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; GCP_CLOUD_RUN &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll have a live URL in under 5 minutes. Add your custom domain, wire up secrets, and set up your CI/CD pipeline — the entire production setup takes under an hour.&lt;/p&gt;

&lt;p&gt;NEXUS AI starts at $29/mo on the Starter plan. Custom domains, Google Cloud Run deployments, and up to 3 team members are included. &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;Start at nexusai.run&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop shipping secrets. Start using a vault.&lt;/li&gt;
&lt;li&gt;RBAC deep dive: roles, scopes, and least privilege&lt;/li&gt;
&lt;li&gt;Audit logs and compliance: what gets recorded and why&lt;/li&gt;
&lt;li&gt;MCP integration: 37 tools for Claude and AI agents&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;No cloud console. No YAML. One command from prompt to production.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>devops</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>Deploy Flixty in minutes with NEXUS AI</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Thu, 09 Apr 2026 23:08:28 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/deploy-flixty-in-minutes-with-nexus-ai-2i21</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/deploy-flixty-in-minutes-with-nexus-ai-2i21</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;5 min read · Beginner friendly · April 2026&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Flixty&lt;/strong&gt; is an open-source, self-hosted social media creator studio that lets you publish to X, LinkedIn, Facebook, Instagram, TikTok, and YouTube from a single interface. NEXUS AI deploys it directly from source — no Dockerfile required — with a single MCP tool call.&lt;/p&gt;

&lt;p&gt;This guide walks you through deploying Flixty on NEXUS AI step by step — covering provider selection, environment variable setup, OAuth configuration for each platform, and ongoing management. By the end you'll have a live, self-hosted social posting studio running on your own cloud infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Flixty?
&lt;/h2&gt;

&lt;p&gt;Flixty (&lt;a href="https://github.com/nexusrun/flixty" rel="noopener noreferrer"&gt;github.com/nexusrun/flixty&lt;/a&gt;) is a Node.js 18+ Express application that serves as a unified control panel for social media publishing. It runs on port &lt;code&gt;3000&lt;/code&gt; and is started with &lt;code&gt;node server.js&lt;/code&gt; — no build step, no container image to maintain.&lt;/p&gt;

&lt;p&gt;Key capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-platform posting&lt;/strong&gt; — schedule and publish content to X, LinkedIn, Facebook, Instagram, TikTok, and YouTube from one dashboard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Assist&lt;/strong&gt; — optional Claude integration (via &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;) generates captions, hashtags, and post variations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Post scheduler&lt;/strong&gt; — queue posts for optimal publish times across time zones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live streaming support&lt;/strong&gt; — manage stream metadata and thumbnails alongside regular posts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth per platform&lt;/strong&gt; — each social network authenticates independently; add only the platforms you need&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;NEXUS AI account&lt;/strong&gt; with at least one project configured&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;NEXUS AI MCP&lt;/strong&gt; connector enabled in Claude — or API access to &lt;code&gt;api.zollo.live/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A supported cloud provider account &lt;em&gt;(GCP, AWS, or Azure)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;OAuth credentials for each social platform you want to enable &lt;em&gt;(X, LinkedIn, Facebook/Instagram, TikTok, Google/YouTube)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; You can deploy Flixty without any platform credentials first to get the public URL, then add OAuth credentials in a redeploy. This is the recommended flow since most OAuth apps require a known redirect URI before you can obtain credentials.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Deploying Flixty — step by step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 — Choose your cloud provider
&lt;/h3&gt;

&lt;p&gt;Flixty is deployed as a source-based deployment — NEXUS AI clones the repo, installs dependencies, and runs &lt;code&gt;node server.js&lt;/code&gt; on your chosen provider. GCP Cloud Run is recommended for production: it handles auto-scaling and provides a stable HTTPS URL you can use for OAuth redirect URIs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GCP Cloud Run&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Serverless, auto-scales to zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS ECS Fargate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full AWS ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Azure Container Apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enterprise &amp;amp; compliance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Environments map to: &lt;code&gt;PRODUCTION&lt;/code&gt; for live traffic (default), &lt;code&gt;STAGING&lt;/code&gt; for pre-production validation, and &lt;code&gt;DEVELOPMENT&lt;/code&gt; for local testing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2 — Deploy with one MCP tool call
&lt;/h3&gt;

&lt;p&gt;Via the NEXUS AI MCP in Claude, call &lt;code&gt;nexusai_deploy_flixty&lt;/code&gt;. A minimal invocation — with no platform credentials yet — looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_flixty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;provider:    &lt;/span&gt;&lt;span class="s2"&gt;"gcp_cloud_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;environment: &lt;/span&gt;&lt;span class="s2"&gt;"PRODUCTION"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;name:        &lt;/span&gt;&lt;span class="s2"&gt;"flixty"&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="sr"&gt;/ optional
)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't supply a &lt;code&gt;sessionSecret&lt;/code&gt;, NEXUS AI auto-generates a cryptographically secure 64-character hex secret for your Express sessions. You can also pass platform OAuth credentials and an &lt;code&gt;anthropicApiKey&lt;/code&gt; at this stage if you have them ready.&lt;/p&gt;

&lt;p&gt;Or deploy from the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy flixty &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; gcp_cloud_run &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--wait&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3 — Save your deployment credentials
&lt;/h3&gt;

&lt;p&gt;After a successful deploy call, NEXUS AI returns:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment UUID&lt;/td&gt;
&lt;td&gt;&lt;code&gt;7a2c91f0-…&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sessionSecret&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Express session signing key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4d8f1c3a9e…&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current state&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;queued&lt;/code&gt; → &lt;code&gt;running&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Public HTTPS endpoint&lt;/td&gt;
&lt;td&gt;Available once live&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Copy your &lt;code&gt;sessionSecret&lt;/code&gt; immediately — it's returned once. Losing it means active user sessions will be invalidated on the next redeploy. Store it in NEXUS AI Secrets or your secrets manager.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 4 — Get the public URL and set BASE_URL
&lt;/h3&gt;

&lt;p&gt;Once the deployment is running, retrieve its public URL and redeploy with &lt;code&gt;BASE_URL&lt;/code&gt; set. This is required for OAuth redirect URIs to work correctly across all platforms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;deploymentId: &lt;/span&gt;&lt;span class="s2"&gt;"7a2c91f0-…"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="sr"&gt;//&lt;/span&gt; &lt;span class="no"&gt;Once&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;have&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redeploy&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="ss"&gt;baseUrl:
&lt;/span&gt;&lt;span class="n"&gt;nexusai_deploy_flixty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;provider:      &lt;/span&gt;&lt;span class="s2"&gt;"gcp_cloud_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;baseUrl:       &lt;/span&gt;&lt;span class="s2"&gt;"https://flixty-abc123.run.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;sessionSecret: &lt;/span&gt;&lt;span class="s2"&gt;"your-saved-session-secret"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;https://flixty.yourdomain.com/auth/&amp;lt;platform&amp;gt;/callback&lt;/code&gt; as the redirect URI when registering your OAuth apps on each platform.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5 — Add platform OAuth credentials
&lt;/h3&gt;

&lt;p&gt;Redeploy with credentials for each platform you want to enable. You can add them all at once or one at a time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_flixty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;provider:            &lt;/span&gt;&lt;span class="s2"&gt;"gcp_cloud_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;baseUrl:             &lt;/span&gt;&lt;span class="s2"&gt;"https://flixty.yourdomain.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;sessionSecret:       &lt;/span&gt;&lt;span class="s2"&gt;"your-saved-session-secret"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;xClientId:           &lt;/span&gt;&lt;span class="s2"&gt;"x-oauth-client-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;xClientSecret:       &lt;/span&gt;&lt;span class="s2"&gt;"x-oauth-client-secret"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;linkedinClientId:    &lt;/span&gt;&lt;span class="s2"&gt;"linkedin-client-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;linkedinClientSecret&lt;/span&gt;&lt;span class="ss"&gt;:"linkedin-client-secret"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;fbAppId:             &lt;/span&gt;&lt;span class="s2"&gt;"facebook-app-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;fbAppSecret:         &lt;/span&gt;&lt;span class="s2"&gt;"facebook-app-secret"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;googleClientId:      &lt;/span&gt;&lt;span class="s2"&gt;"google-client-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;googleClientSecret:  &lt;/span&gt;&lt;span class="s2"&gt;"google-client-secret"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;anthropicApiKey:     &lt;/span&gt;&lt;span class="s2"&gt;"sk-ant-…"&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="sr"&gt;/ enables AI Assist
)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;fbAppId&lt;/code&gt; and &lt;code&gt;fbAppSecret&lt;/code&gt; enable both Facebook and Instagram. A single Facebook App handles both platforms via the Graph API.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Environment variables reference
&lt;/h2&gt;

&lt;p&gt;All variables are injected securely at runtime. None are baked into the image.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SESSION_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Express session signing key. Auto-generated (64-char hex) if not provided.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BASE_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes*&lt;/td&gt;
&lt;td&gt;Public HTTPS URL of your deployment. Required for OAuth redirect URIs. Set after first deploy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PORT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-set&lt;/td&gt;
&lt;td&gt;Always &lt;code&gt;3000&lt;/code&gt;. Set automatically by NEXUS AI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NODE_ENV&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-set&lt;/td&gt;
&lt;td&gt;Always &lt;code&gt;production&lt;/code&gt; for PRODUCTION environment deployments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Enables AI Assist (claude-sonnet-4-6) for caption generation and post variations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X_CLIENT_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;X/Twitter OAuth 2.0 Client ID. Required to enable X posting.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;X_CLIENT_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;X/Twitter OAuth 2.0 Client Secret.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LINKEDIN_CLIENT_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;LinkedIn OAuth Client ID. Required to enable LinkedIn posting.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LINKEDIN_CLIENT_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;LinkedIn OAuth Client Secret.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FB_APP_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Facebook App ID. Enables both Facebook and Instagram via the Graph API.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FB_APP_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Facebook App Secret.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TIKTOK_CLIENT_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;TikTok Client Key. Required to enable TikTok posting.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TIKTOK_CLIENT_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;TikTok Client Secret.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GOOGLE_CLIENT_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Google OAuth Client ID. Enables YouTube posting and Google Sign-In.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GOOGLE_CLIENT_SECRET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Google OAuth Client Secret.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*&lt;code&gt;BASE_URL&lt;/code&gt; is technically optional on first deploy when the public URL is not yet known. Set it on the first redeploy once the deployment is running.&lt;/p&gt;




&lt;h2&gt;
  
  
  Managing your Flixty deployment
&lt;/h2&gt;

&lt;p&gt;NEXUS AI gives you full lifecycle control over every deployment. Here's a quick reference:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;MCP Tool&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Check status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After deploying, or to get the public URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View logs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_logs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Debug OAuth errors or startup failures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redeploy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_redeploy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push updated env vars or a new code revision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stop studio&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_stop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pause to save compute costs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restart&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After a stop, or after config changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_rollback&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Revert to a previous working revision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nexusai_deploy_delete&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Permanently tear down the deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Scaling your deployment
&lt;/h3&gt;

&lt;p&gt;Scale Flixty up to handle more concurrent users without redeploying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;deploymentId: &lt;/span&gt;&lt;span class="s2"&gt;"7a2c91f0-…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;replicas:     &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy scale flixty 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Custom domain
&lt;/h3&gt;

&lt;p&gt;Attach a custom domain so your OAuth redirect URIs stay stable across redeployments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_domains_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;deploymentId: &lt;/span&gt;&lt;span class="s2"&gt;"7a2c91f0-…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;domain:       &lt;/span&gt;&lt;span class="s2"&gt;"flixty.yourdomain.com"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Set up a custom domain before registering OAuth apps so your redirect URIs never change. Use &lt;code&gt;https://flixty.yourdomain.com/auth/&amp;lt;platform&amp;gt;/callback&lt;/code&gt; as the redirect URI template.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  OAuth redirects fail after deploy
&lt;/h3&gt;

&lt;p&gt;This means &lt;code&gt;BASE_URL&lt;/code&gt; is not set or points to the wrong URL. Check the current value with &lt;code&gt;nexusai_deploy_status&lt;/code&gt; and redeploy with the correct public HTTPS URL. All OAuth callbacks are constructed from &lt;code&gt;BASE_URL&lt;/code&gt; at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Posts fail for a specific platform
&lt;/h3&gt;

&lt;p&gt;The platform credentials for that network are missing or incorrect. Check that the relevant env vars (&lt;code&gt;X_CLIENT_ID&lt;/code&gt;, &lt;code&gt;FB_APP_ID&lt;/code&gt;, etc.) are set via &lt;code&gt;nexusai_deploy_status&lt;/code&gt;. Use &lt;code&gt;nexusai_deploy_logs&lt;/code&gt; to see the exact OAuth error returned by the platform's API.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Assist not working
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; is not set or the key is invalid. Redeploy with a valid Anthropic API key. Verify it starts with &lt;code&gt;sk-ant-&lt;/code&gt; and has not expired or been revoked in your Anthropic console.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment stuck in "queued"
&lt;/h3&gt;

&lt;p&gt;Check that your cloud provider credentials are properly configured in NEXUS AI. For GCP, ensure your service account has Cloud Run developer permissions. Use &lt;code&gt;nexusai_deploy_logs&lt;/code&gt; to diagnose any build or startup failures — common causes are missing Node.js version compatibility or a &lt;code&gt;package.json&lt;/code&gt; install failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Session errors after redeploy
&lt;/h3&gt;

&lt;p&gt;If you redeploy without passing the original &lt;code&gt;sessionSecret&lt;/code&gt;, a new secret is generated and all existing user sessions are invalidated. Always save and re-pass &lt;code&gt;sessionSecret&lt;/code&gt; on subsequent deploys to maintain session continuity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Flixty on NEXUS AI gives you a fully self-hosted social media publishing stack — no third-party SaaS dependencies, no per-seat pricing, no data leaving your cloud. You control the OAuth tokens, the session data, and the posting schedule.&lt;/p&gt;

&lt;p&gt;From here, explore attaching a custom domain for stable OAuth redirect URIs, enabling AI Assist with your Anthropic API key, or setting up a staging environment to test platform integrations before they go live.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try it now:&lt;/strong&gt; Head to &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;nexusai.run&lt;/a&gt; and enable the NEXUS AI MCP connector in Claude to deploy Flixty with a single conversation in under 5 minutes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;NEXUS AI — AI-native cloud infrastructure · &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;nexusai.run&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flixty</category>
      <category>devops</category>
      <category>nexusai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I replaced my entire GitHub Actions deploy pipeline with one command</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Tue, 07 Apr 2026 16:56:29 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/i-replaced-my-entire-github-actions-deploy-pipeline-with-one-command-2o0j</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/i-replaced-my-entire-github-actions-deploy-pipeline-with-one-command-2o0j</guid>
      <description>&lt;p&gt;&lt;strong&gt;My GitHub Actions deploy workflow was 87 lines of YAML.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It had grown over 18 months from a clean 20-line file into something I was genuinely afraid to touch. It broke whenever a dependency updated. It had three hardcoded ARNs from an AWS account I was no longer using. It had a comment that said &lt;code&gt;# TODO: fix this&lt;/code&gt; that had been there for 11 months.&lt;/p&gt;

&lt;p&gt;Last month I deleted all 87 lines and replaced them with one command.&lt;/p&gt;

&lt;p&gt;Here's exactly how I did it — and what I learned along the way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The YAML graveyard
&lt;/h2&gt;

&lt;p&gt;This was my deploy workflow. See if any of this feels familiar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;aws-access-key-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;aws-secret-access-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Login to Amazon ECR&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;login-ecr&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecr-login@v1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Docker image&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ECR_REGISTRY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.login-ecr.outputs.registry }}&lt;/span&gt;
          &lt;span class="na"&gt;IMAGE_TAG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.sha }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker build -t $ECR_REGISTRY/my-app:$IMAGE_TAG .&lt;/span&gt;
          &lt;span class="s"&gt;docker push $ECR_REGISTRY/my-app:$IMAGE_TAG&lt;/span&gt;
          &lt;span class="s"&gt;echo "IMAGE=$ECR_REGISTRY/my-app:$IMAGE_TAG" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Download task definition&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;aws ecs describe-task-definition --task-definition my-app \&lt;/span&gt;
            &lt;span class="s"&gt;--query taskDefinition &amp;gt; task-definition.json&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update ECS task definition&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;task-def&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecs-render-task-definition@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;task-definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;task-definition.json&lt;/span&gt;
          &lt;span class="na"&gt;container-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.IMAGE }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to ECS&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecs-deploy-task-definition@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;task-definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.task-def.outputs.task-definition }}&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app-service&lt;/span&gt;
          &lt;span class="na"&gt;cluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app-cluster&lt;/span&gt;
          &lt;span class="na"&gt;wait-for-service-stability&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Notify on failure&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;failure()&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} \&lt;/span&gt;
            &lt;span class="s"&gt;-H 'Content-type: application/json' \&lt;/span&gt;
            &lt;span class="s"&gt;--data '{"text":"Deploy failed! Check Actions."}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wrote this. I'm not proud of it.&lt;/p&gt;

&lt;p&gt;The real problem wasn't the YAML itself. The problem was everything hidden &lt;em&gt;underneath&lt;/em&gt; the YAML:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ECR repository I had to provision manually&lt;/li&gt;
&lt;li&gt;An ECS cluster, service, and task definition I had to set up in the console&lt;/li&gt;
&lt;li&gt;IAM roles with the exact right permissions (I guessed wrong twice)&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;Dockerfile&lt;/code&gt; I maintained separately&lt;/li&gt;
&lt;li&gt;AWS credentials rotated manually every 90 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pipeline was the visible part. The invisible part was 3 days of setup I did 18 months ago that I could no longer remember well enough to recreate.&lt;/p&gt;

&lt;p&gt;When a new teammate joined and asked "how does deploy work?" — I sent them the workflow file and said "it's complicated."&lt;/p&gt;

&lt;p&gt;That's not an answer. That's a warning sign.&lt;/p&gt;




&lt;h2&gt;
  
  
  The breaking point
&lt;/h2&gt;

&lt;p&gt;In February, I switched from Node 18 to Node 20. The Docker build broke because my base image was pinned to &lt;code&gt;node:18-alpine&lt;/code&gt; in three different places — the Dockerfile, the Actions workflow, and a &lt;code&gt;.nvmrc&lt;/code&gt; file I had forgotten existed.&lt;/p&gt;

&lt;p&gt;The fix took 45 minutes. The error message was not helpful. I fixed it by diffing my Dockerfile against a Stack Overflow answer from 2023.&lt;/p&gt;

&lt;p&gt;Two weeks later, AWS deprecated the &lt;code&gt;amazon-ecs-render-task-definition@v1&lt;/code&gt; action. The pipeline broke silently — it ran, reported success, but the new image never actually deployed. I found out because a user filed a bug for something I had &lt;em&gt;definitely&lt;/em&gt; already fixed.&lt;/p&gt;

&lt;p&gt;That was the moment I decided: the pipeline is not worth maintaining.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I tried first
&lt;/h2&gt;

&lt;p&gt;I looked at Render and Railway. Both are good products. Neither deploys into my own AWS account — they provision their own infrastructure. My company has a compliance requirement that customer data stays in a customer-owned AWS environment. So those were out.&lt;/p&gt;

&lt;p&gt;I looked at AWS CodePipeline. I wanted to solve complexity, not add more of it.&lt;/p&gt;

&lt;p&gt;Then a colleague mentioned &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;NEXUS AI&lt;/a&gt;. He described it as "a CLI that handles all the ECS stuff so you don't have to." I was skeptical. That's what everyone says.&lt;/p&gt;




&lt;h2&gt;
  
  
  The initial deploy
&lt;/h2&gt;

&lt;p&gt;I installed the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @nexusai/cli
nexus login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I pointed it at my repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/myorg/my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; aws_ecs_fargate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expected this to fail immediately. My expectations for new DevOps tools are calibrated by years of experience.&lt;/p&gt;

&lt;p&gt;It didn't fail. Four and a half minutes later I got back a URL. The app was running. The same app. In my AWS account.&lt;/p&gt;

&lt;p&gt;I checked the AWS console out of habit. There was an ECS cluster. A task definition. A service. An ECR repository with the image in it. NEXUS AI had provisioned all of it.&lt;/p&gt;

&lt;p&gt;I had not written a Dockerfile. I had not configured any IAM roles. I had not touched the AWS console.&lt;/p&gt;

&lt;p&gt;I sat with that for a moment.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually happens under the hood
&lt;/h2&gt;

&lt;p&gt;Here's what &lt;code&gt;nexus deploy source&lt;/code&gt; does, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reads your repo&lt;/strong&gt; — detects the runtime from &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;requirements.txt&lt;/code&gt;, &lt;code&gt;go.mod&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Builds the container&lt;/strong&gt; on NEXUS AI's build infrastructure — not your machine, not a GitHub runner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pushes the image&lt;/strong&gt; to an ECR repository it provisions in your account&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creates (or updates) the ECS infrastructure&lt;/strong&gt; — cluster, task definition, service, load balancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issues a TLS certificate&lt;/strong&gt; via ACM and wires it to the load balancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Waits for health checks&lt;/strong&gt; to pass before returning the live URL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps 3–5 are the 3 days of manual work I did 18 months ago. They now run in parallel and take about 3 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The new GitHub Actions workflow
&lt;/h2&gt;

&lt;p&gt;Here's my deploy workflow today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nexus deploy redeploy --deployment-id ${{ secrets.NEXUSAI_DEPLOYMENT_ID }}&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NEXUSAI_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NEXUSAI_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;24 lines, including &lt;code&gt;name:&lt;/code&gt; fields and blank lines.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;deploy&lt;/code&gt; job has one step. It calls &lt;code&gt;nexus deploy redeploy&lt;/code&gt;, which tells NEXUS AI to rebuild from the latest commit and roll it out with a rolling update. No Docker commands. No AWS credentials. No ECR. No ECS task definition wrangling.&lt;/p&gt;

&lt;p&gt;I kept the &lt;code&gt;test&lt;/code&gt; job. NEXUS AI doesn't replace your test suite — it replaces everything &lt;em&gt;after&lt;/em&gt; tests pass.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secrets and environment variables
&lt;/h2&gt;

&lt;p&gt;Before, I had secrets in three places: GitHub Actions secrets (for the pipeline), AWS Secrets Manager (for the app), and a &lt;code&gt;.env.example&lt;/code&gt; file that was always slightly out of date.&lt;/p&gt;

&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus secret &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres://user:pass@host/db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;STRIPE_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk_live_... &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are encrypted at rest and injected as environment variables when the container starts. The pipeline only needs &lt;code&gt;NEXUSAI_TOKEN&lt;/code&gt; — one secret instead of seven.&lt;/p&gt;

&lt;p&gt;After updating secrets, one command applies them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy redeploy &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;your-deployment-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Rollback
&lt;/h2&gt;

&lt;p&gt;Old workflow rollback: figure out the previous image SHA, manually update the ECS task definition, trigger a new deployment, hope the old image hasn't been cleaned up by the ECR lifecycle policy.&lt;/p&gt;

&lt;p&gt;New rollback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy rollback &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;your-deployment-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reverts to the previous container image. Health checks run. Done. I've used this twice. Both times took under 90 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Redeployment speed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;First deploy:&lt;/strong&gt; ~4.5 minutes (infrastructure provisioning included).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subsequent deploys:&lt;/strong&gt; 60–90 seconds. Infrastructure is already provisioned, so it's just build → push → rolling update.&lt;/p&gt;

&lt;p&gt;My old pipeline took 10–12 minutes. Most of that was the Docker build running on GitHub's shared runners plus the ECS service stability wait.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I lost
&lt;/h2&gt;

&lt;p&gt;Every tool has trade-offs. These are the real ones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Less visibility into the build environment.&lt;/strong&gt; With a Dockerfile I wrote, I knew exactly what was in the image. With source-based deployment, NEXUS AI generates the image. You can inspect it — &lt;code&gt;nexus deploy logs&lt;/code&gt; gives the full build output — but you're not authoring the Dockerfile. For most apps this is fine. If you have specific system dependencies (custom C extensions, obscure shared libraries), test carefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first deploy takes time.&lt;/strong&gt; Infrastructure provisioning isn't instant. If you need sub-30-second cold deploys for some reason, this isn't that. But once infrastructure exists, redeployments are fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're adding a dependency.&lt;/strong&gt; NEXUS AI is now in your deploy path. Worth knowing.&lt;/p&gt;




&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Old workflow&lt;/th&gt;
&lt;th&gt;New workflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lines of YAML&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline runtime&lt;/td&gt;
&lt;td&gt;10–12 min&lt;/td&gt;
&lt;td&gt;60–90 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS console setup&lt;/td&gt;
&lt;td&gt;~3 days (one-time)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets locations&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback steps&lt;/td&gt;
&lt;td&gt;~6 manual steps&lt;/td&gt;
&lt;td&gt;1 command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Last random breakage&lt;/td&gt;
&lt;td&gt;November&lt;/td&gt;
&lt;td&gt;Hasn't happened&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How to try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @nexusai/cli

&lt;span class="c"&gt;# Authenticate&lt;/span&gt;
nexus login

&lt;span class="c"&gt;# First deploy — detects Node/Python/Go automatically, no Dockerfile needed&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/your/repo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; aws_ecs_fargate   &lt;span class="c"&gt;# or gcp_cloud_run, azure_container_apps&lt;/span&gt;

&lt;span class="c"&gt;# Check status&lt;/span&gt;
nexus deploy status &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# Set environment variables&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value &lt;span class="nv"&gt;KEY2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value2

&lt;span class="c"&gt;# Redeploy (use this in CI)&lt;/span&gt;
nexus deploy redeploy &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# Rollback&lt;/span&gt;
nexus deploy rollback &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For CI/CD: add &lt;code&gt;NEXUSAI_TOKEN&lt;/code&gt; and &lt;code&gt;NEXUSAI_DEPLOYMENT_ID&lt;/code&gt; as secrets in your GitHub repo settings, then replace your deploy steps with the one-liner from the workflow above.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;The 87-line YAML file wasn't the real cost. The real cost was the cognitive overhead of owning it — the 45-minute debugging session when Node versions drifted, the silent failure when an Action was deprecated, the "it's complicated" I sent to a new teammate.&lt;/p&gt;

&lt;p&gt;I don't miss any of that.&lt;/p&gt;

&lt;p&gt;If you're maintaining a pipeline like the one I had, it's worth spending 20 minutes to find out how much of it you can delete.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building something and want to compare notes? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I replaced my entire GitHub Actions deploy pipeline with one command</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sat, 04 Apr 2026 11:14:28 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/i-replaced-my-entire-github-actions-deploy-pipeline-with-one-command-2h95</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/i-replaced-my-entire-github-actions-deploy-pipeline-with-one-command-2h95</guid>
      <description>&lt;p&gt;My GitHub Actions deploy workflow was 87 lines of YAML.&lt;/p&gt;

&lt;p&gt;It had grown over 18 months from a clean 20-line file into something I was genuinely afraid to touch. It broke whenever a dependency updated. It had three hardcoded ARNs from an AWS account I was no longer using. It had a comment that said &lt;code&gt;# TODO: fix this&lt;/code&gt; that had been there for 11 months.&lt;/p&gt;

&lt;p&gt;Last month I deleted all 87 lines and replaced them with one command.&lt;/p&gt;

&lt;p&gt;Here's exactly how I did it — and what I learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The YAML graveyard
&lt;/h2&gt;

&lt;p&gt;This was my deploy workflow. See if any of this feels familiar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure AWS credentials&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;aws-access-key-id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_ACCESS_KEY_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;aws-secret-access-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AWS_SECRET_ACCESS_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Login to Amazon ECR&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;login-ecr&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecr-login@v1&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Docker image&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ECR_REGISTRY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.login-ecr.outputs.registry }}&lt;/span&gt;
          &lt;span class="na"&gt;IMAGE_TAG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.sha }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker build -t $ECR_REGISTRY/my-app:$IMAGE_TAG .&lt;/span&gt;
          &lt;span class="s"&gt;docker push $ECR_REGISTRY/my-app:$IMAGE_TAG&lt;/span&gt;
          &lt;span class="s"&gt;echo "IMAGE=$ECR_REGISTRY/my-app:$IMAGE_TAG" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Download task definition&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;aws ecs describe-task-definition --task-definition my-app \&lt;/span&gt;
            &lt;span class="s"&gt;--query taskDefinition &amp;gt; task-definition.json&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update ECS task definition&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;task-def&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecs-render-task-definition@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;task-definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;task-definition.json&lt;/span&gt;
          &lt;span class="na"&gt;container-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.IMAGE }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to ECS&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecs-deploy-task-definition@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;task-definition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.task-def.outputs.task-definition }}&lt;/span&gt;
          &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app-service&lt;/span&gt;
          &lt;span class="na"&gt;cluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app-cluster&lt;/span&gt;
          &lt;span class="na"&gt;wait-for-service-stability&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Notify on failure&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;failure()&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} \&lt;/span&gt;
            &lt;span class="s"&gt;-H 'Content-type: application/json' \&lt;/span&gt;
            &lt;span class="s"&gt;--data '{"text":"Deploy failed! Check Actions."}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wrote this. I'm not proud of it.&lt;/p&gt;

&lt;p&gt;The real problem wasn't the YAML itself. The problem was everything hidden &lt;em&gt;underneath&lt;/em&gt; the YAML:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ECR repository I had to provision manually&lt;/li&gt;
&lt;li&gt;An ECS cluster, service, and task definition I had to set up in the console&lt;/li&gt;
&lt;li&gt;IAM roles with the exact right permissions (I guessed wrong twice)&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;Dockerfile&lt;/code&gt; I maintained separately&lt;/li&gt;
&lt;li&gt;AWS credentials rotated manually every 90 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pipeline was the visible part. The invisible part was 3 days of setup I did 18 months ago that I could no longer remember well enough to recreate.&lt;/p&gt;

&lt;p&gt;When a new teammate joined and asked "how does deploy work?" — I sent them the workflow file and said "it's complicated."&lt;/p&gt;

&lt;p&gt;That's not an answer. That's a warning sign.&lt;/p&gt;




&lt;h2&gt;
  
  
  The breaking point
&lt;/h2&gt;

&lt;p&gt;In February, I switched from Node 18 to Node 20. The Docker build broke because my base image was pinned to &lt;code&gt;node:18-alpine&lt;/code&gt; in three different places — the Dockerfile, the Actions workflow, and a &lt;code&gt;.nvmrc&lt;/code&gt; file I had forgotten existed.&lt;/p&gt;

&lt;p&gt;The fix took 45 minutes. The error message was not helpful. I fixed it by diffing my Dockerfile against a Stack Overflow answer from 2023.&lt;/p&gt;

&lt;p&gt;Two weeks later, AWS deprecated the &lt;code&gt;amazon-ecs-render-task-definition@v1&lt;/code&gt; action. The pipeline broke silently — it ran, reported success, but the new image never actually deployed. I found out because a user filed a bug for something I had &lt;em&gt;definitely&lt;/em&gt; already fixed.&lt;/p&gt;

&lt;p&gt;That was the moment I decided: the pipeline is not worth maintaining.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I tried first
&lt;/h2&gt;

&lt;p&gt;I looked at Render and Railway. Both are good products. Neither deploys into my own AWS account — they provision their own infrastructure. My company has a compliance requirement that customer data stays in a customer-owned AWS environment. So those were out.&lt;/p&gt;

&lt;p&gt;I looked at AWS CodePipeline. I wanted to solve complexity, not add more of it.&lt;/p&gt;

&lt;p&gt;Then a colleague mentioned &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;NEXUS AI&lt;/a&gt;. He described it as "a CLI that handles all the ECS stuff so you don't have to." I was skeptical. That's what everyone says.&lt;/p&gt;




&lt;h2&gt;
  
  
  The initial deploy
&lt;/h2&gt;

&lt;p&gt;I installed the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @nexusai/cli
nexus login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I pointed it at my repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/myorg/my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; aws_ecs_fargate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I expected this to fail immediately. My expectations for new DevOps tools are calibrated by years of experience.&lt;/p&gt;

&lt;p&gt;It didn't fail. Four and a half minutes later I got back a URL. The app was running. The same app. In my AWS account.&lt;/p&gt;

&lt;p&gt;I checked the AWS console out of habit. There was an ECS cluster. A task definition. A service. An ECR repository with the image in it. NEXUS AI had provisioned all of it.&lt;/p&gt;

&lt;p&gt;I had not written a Dockerfile. I had not configured any IAM roles. I had not touched the AWS console.&lt;/p&gt;

&lt;p&gt;I sat with that for a moment.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually happens under the hood
&lt;/h2&gt;

&lt;p&gt;Here's what &lt;code&gt;nexus deploy source&lt;/code&gt; does, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reads your repo&lt;/strong&gt; — detects the runtime from &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;requirements.txt&lt;/code&gt;, &lt;code&gt;go.mod&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Builds the container&lt;/strong&gt; on NEXUS AI's build infrastructure — not your machine, not a GitHub runner&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pushes the image&lt;/strong&gt; to an ECR repository it provisions in your account&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creates (or updates) the ECS infrastructure&lt;/strong&gt; — cluster, task definition, service, load balancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issues a TLS certificate&lt;/strong&gt; via ACM and wires it to the load balancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Waits for health checks&lt;/strong&gt; to pass before returning the live URL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps 3–5 are the 3 days of manual work I did 18 months ago. They now run in parallel and take about 3 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The new GitHub Actions workflow
&lt;/h2&gt;

&lt;p&gt;Here's my deploy workflow today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;npm'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;

  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nexus deploy redeploy --deployment-id ${{ secrets.NEXUSAI_DEPLOYMENT_ID }}&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;NEXUSAI_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NEXUSAI_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;24 lines, including &lt;code&gt;name:&lt;/code&gt; fields and blank lines.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;deploy&lt;/code&gt; job has one step. It calls &lt;code&gt;nexus deploy redeploy&lt;/code&gt;, which tells NEXUS AI to rebuild from the latest commit and roll it out with a rolling update. No Docker commands. No AWS credentials. No ECR. No ECS task definition wrangling.&lt;/p&gt;

&lt;p&gt;I kept the &lt;code&gt;test&lt;/code&gt; job. NEXUS AI doesn't replace your test suite — it replaces everything &lt;em&gt;after&lt;/em&gt; tests pass.&lt;/p&gt;




&lt;h2&gt;
  
  
  Secrets and environment variables
&lt;/h2&gt;

&lt;p&gt;Before, I had secrets in three places: GitHub Actions secrets (for the pipeline), AWS Secrets Manager (for the app), and a &lt;code&gt;.env.example&lt;/code&gt; file that was always slightly out of date.&lt;/p&gt;

&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus secret &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgres://user:pass@host/db &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;STRIPE_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk_live_... &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are encrypted at rest and injected as environment variables when the container starts. The pipeline only needs &lt;code&gt;NEXUSAI_TOKEN&lt;/code&gt; — one secret instead of seven.&lt;/p&gt;

&lt;p&gt;After updating secrets, one command applies them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy redeploy &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;your-deployment-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Rollback
&lt;/h2&gt;

&lt;p&gt;Old workflow rollback: figure out the previous image SHA, manually update the ECS task definition, trigger a new deployment, hope the old image hasn't been cleaned up by the ECR lifecycle policy.&lt;/p&gt;

&lt;p&gt;New rollback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy rollback &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;your-deployment-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reverts to the previous container image. Health checks run. Done. I've used this twice. Both times took under 90 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Redeployment speed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;First deploy:&lt;/strong&gt; ~4.5 minutes (infrastructure provisioning included).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subsequent deploys:&lt;/strong&gt; 60–90 seconds. Infrastructure is already provisioned, so it's just build → push → rolling update.&lt;/p&gt;

&lt;p&gt;My old pipeline took 10–12 minutes. Most of that was the Docker build running on GitHub's shared runners plus the ECS service stability wait.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I lost
&lt;/h2&gt;

&lt;p&gt;Every tool has trade-offs. These are the real ones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Less visibility into the build environment.&lt;/strong&gt; With a Dockerfile I wrote, I knew exactly what was in the image. With source-based deployment, NEXUS AI generates the image. You can inspect it — &lt;code&gt;nexus deploy logs&lt;/code&gt; gives the full build output — but you're not authoring the Dockerfile. For most apps this is fine. If you have specific system dependencies (custom C extensions, obscure shared libraries), test carefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first deploy takes time.&lt;/strong&gt; Infrastructure provisioning isn't instant. If you need sub-30-second cold deploys for some reason, this isn't that. But once infrastructure exists, redeployments are fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're adding a dependency.&lt;/strong&gt; NEXUS AI is now in your deploy path. Worth knowing.&lt;/p&gt;




&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Old workflow&lt;/th&gt;
&lt;th&gt;New workflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lines of YAML&lt;/td&gt;
&lt;td&gt;87&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline runtime&lt;/td&gt;
&lt;td&gt;10–12 min&lt;/td&gt;
&lt;td&gt;60–90 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS console setup&lt;/td&gt;
&lt;td&gt;~3 days (one-time)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets locations&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback steps&lt;/td&gt;
&lt;td&gt;~6 manual steps&lt;/td&gt;
&lt;td&gt;1 command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Last random breakage&lt;/td&gt;
&lt;td&gt;November&lt;/td&gt;
&lt;td&gt;Hasn't happened&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How to try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @nexusai/cli

&lt;span class="c"&gt;# Authenticate&lt;/span&gt;
nexus login

&lt;span class="c"&gt;# First deploy — detects Node/Python/Go automatically, no Dockerfile needed&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/your/repo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; aws_ecs_fargate   &lt;span class="c"&gt;# or gcp_cloud_run, azure_container_apps&lt;/span&gt;

&lt;span class="c"&gt;# Check status&lt;/span&gt;
nexus deploy status &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# Set environment variables&lt;/span&gt;
nexus secret &lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value &lt;span class="nv"&gt;KEY2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;value2

&lt;span class="c"&gt;# Redeploy (use this in CI)&lt;/span&gt;
nexus deploy redeploy &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# Rollback&lt;/span&gt;
nexus deploy rollback &lt;span class="nt"&gt;--deployment-id&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For CI/CD: add &lt;code&gt;NEXUSAI_TOKEN&lt;/code&gt; and &lt;code&gt;NEXUSAI_DEPLOYMENT_ID&lt;/code&gt; as secrets in your GitHub repo settings, then replace your deploy steps with the one-liner from the workflow above.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;The 87-line YAML file wasn't the real cost. The real cost was the cognitive overhead of owning it — the 45-minute debugging session when Node versions drifted, the silent failure when an Action was deprecated, the "it's complicated" I sent to a new teammate.&lt;/p&gt;

&lt;p&gt;I don't miss any of that.&lt;/p&gt;

&lt;p&gt;If you're maintaining a pipeline like the one I had, it's worth spending 20 minutes to find out how much of it you can delete.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building something and want to compare notes? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>github</category>
      <category>deployment</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Complete Claude Code Tutorial: Build and Deploy an AI App in an Afternoon</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sun, 29 Mar 2026 15:16:16 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/the-complete-claude-code-tutorial-build-and-deploy-an-ai-app-in-an-afternoon-4ij</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/the-complete-claude-code-tutorial-build-and-deploy-an-ai-app-in-an-afternoon-4ij</guid>
      <description>&lt;p&gt;Most Claude Code tutorials stop at "here's how to install it." That's like teaching someone to drive by showing them the ignition. This Claude Code tutorial goes further — you'll use it to build a real AI-powered app from scratch and deploy it to production, step by step.&lt;/p&gt;

&lt;p&gt;By the end you'll have a working document Q&amp;amp;A API and a live deployment URL. The whole thing takes about an afternoon.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Claude Code actually is (and why it's different)
&lt;/h2&gt;

&lt;p&gt;Claude Code is Anthropic's AI coding agent that runs in your terminal. Unlike copilot-style tools that suggest individual lines inside an editor, Claude Code operates at the project level — it reads your entire codebase, understands how files relate to each other, and makes multi-file changes with full context.&lt;/p&gt;

&lt;p&gt;The practical difference: you describe what you want to build, and Claude Code writes the code, runs commands, fixes errors, and iterates — without you switching between a chat window and your editor. It's AI-augmented development where the AI is a collaborator in your actual workflow, not a suggestion box beside it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it powerful for AI app development specifically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It can generate boilerplate for FastAPI, Express, or any framework in seconds&lt;/li&gt;
&lt;li&gt;It writes tests alongside the code it generates&lt;/li&gt;
&lt;li&gt;It catches its own mistakes by running the code and reading error output&lt;/li&gt;
&lt;li&gt;It handles the tedious parts (CI config, requirements.txt, test scaffolding) while you focus on the actual problem&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting started: install and configure Claude Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requires Node.js 18+. Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authenticate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On first run, Claude Code opens a browser window to authenticate with your Anthropic account. Once authenticated, it drops you into an interactive session in your current directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your first command
&lt;/h3&gt;

&lt;p&gt;Navigate to an empty project folder and try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-ai-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;my-ai-app
claude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Claude Code prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Scaffold a FastAPI project with a single /health endpoint, a requirements.txt, and a .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code will create the files, show you what it's doing, and confirm. This is the core interaction pattern: describe the outcome, let it execute.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build a real AI app with Claude Code
&lt;/h2&gt;

&lt;p&gt;We're building a &lt;strong&gt;document Q&amp;amp;A API&lt;/strong&gt; — you upload a text document, ask questions about it, and get answers grounded in the document's content. It's a practical RAG (retrieval-augmented generation) pattern used in real products.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Scaffold the project
&lt;/h3&gt;

&lt;p&gt;In your Claude Code session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Create a FastAPI app for document Q&amp;amp;A. The app should:
&amp;gt; - Accept a POST /upload endpoint that takes a text file and stores it in memory
&amp;gt; - Accept a POST /ask endpoint that takes a document_id and a question, then answers using OpenAI gpt-4o-mini
&amp;gt; - Return answers in JSON with the answer text and a confidence field
&amp;gt; - Include a requirements.txt with fastapi, uvicorn, openai, and python-multipart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code will generate the full project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-ai-app/
├── main.py
├── requirements.txt
├── .gitignore
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It writes the entire &lt;code&gt;main.py&lt;/code&gt; — endpoints, in-memory document store, OpenAI call — in one pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Run it and fix errors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Run the app locally with uvicorn and show me any errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code executes &lt;code&gt;uvicorn main:app --reload&lt;/code&gt;, reads the output, and if there are import errors or missing packages it fixes them automatically. This loop — run, read error, fix — is where Claude Code earns its keep. You don't context-switch; it just handles it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Add real retrieval (not just stuffing the whole document)
&lt;/h3&gt;

&lt;p&gt;The naive version sends the entire document to the model on every question. That breaks on large files and wastes tokens. Ask Claude Code to improve it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; The current /ask endpoint sends the full document to OpenAI on every request.
&amp;gt; Refactor it to:
&amp;gt; - Split documents into 500-token chunks on upload
&amp;gt; - Use cosine similarity on TF-IDF vectors to find the top 3 relevant chunks
&amp;gt; - Only send those 3 chunks to OpenAI as context
&amp;gt; - Use numpy and sklearn for the vector operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is multi-file, multi-concept work. Claude Code will update &lt;code&gt;main.py&lt;/code&gt;, add &lt;code&gt;sklearn&lt;/code&gt; and &lt;code&gt;numpy&lt;/code&gt; to &lt;code&gt;requirements.txt&lt;/code&gt;, and implement the chunking + retrieval logic coherently. It understands that changing the upload flow affects the query flow and handles both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Write tests
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Write pytest tests for both endpoints. Include:
&amp;gt; - A test that uploads a sample document and verifies the document_id is returned
&amp;gt; - A test that uploads a document, then asks a question whose answer is clearly in the document
&amp;gt; - A test that asks about a document_id that doesn't exist and expects a 404
&amp;gt; Mock the OpenAI call so tests don't need a real API key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code generates &lt;code&gt;test_main.py&lt;/code&gt; with the exact structure you described, uses &lt;code&gt;pytest-mock&lt;/code&gt; for the OpenAI mock, and adds the test dependencies to &lt;code&gt;requirements.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Run the tests and fix any failures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code runs &lt;code&gt;pytest&lt;/code&gt;, reads the output, and iterates until they pass. The critical detail: it doesn't just generate tests and hand them back — it runs them and closes the feedback loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  The CLAUDE.md file: your project's AI instruction layer
&lt;/h2&gt;

&lt;p&gt;One of the most underused Claude Code features is &lt;code&gt;CLAUDE.md&lt;/code&gt; — a file in your project root that Claude Code reads at the start of every session. Think of it as a permanent briefing document for your AI collaborator.&lt;/p&gt;

&lt;p&gt;Create one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Create a CLAUDE.md for this project that documents:
&amp;gt; - The tech stack (FastAPI, OpenAI, sklearn)
&amp;gt; - The coding conventions we used (snake_case, type hints everywhere, docstrings on public functions)
&amp;gt; - The test setup (pytest, mock OpenAI calls)
&amp;gt; - What the /upload and /ask endpoints do
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this point on, any new Claude Code session on this project starts with full context. You don't re-explain the stack every time.&lt;/p&gt;

&lt;p&gt;A good &lt;code&gt;CLAUDE.md&lt;/code&gt; includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Project: Document Q&amp;amp;A API&lt;/span&gt;

&lt;span class="gu"&gt;## Stack&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; FastAPI + Uvicorn (Python 3.11)
&lt;span class="p"&gt;-&lt;/span&gt; OpenAI gpt-4o-mini for generation
&lt;span class="p"&gt;-&lt;/span&gt; sklearn TF-IDF + cosine similarity for retrieval
&lt;span class="p"&gt;-&lt;/span&gt; pytest + pytest-mock for testing

&lt;span class="gu"&gt;## Conventions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Type hints on all function signatures
&lt;span class="p"&gt;-&lt;/span&gt; Snake_case everywhere
&lt;span class="p"&gt;-&lt;/span&gt; Docstrings on all public functions

&lt;span class="gu"&gt;## Architecture&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Documents stored in-memory (dict keyed by UUID)
&lt;span class="p"&gt;-&lt;/span&gt; Chunks: 500 tokens, 50-token overlap
&lt;span class="p"&gt;-&lt;/span&gt; Top 3 chunks retrieved per query

&lt;span class="gu"&gt;## Running locally&lt;/span&gt;
uvicorn main:app --reload --port 8000

&lt;span class="gu"&gt;## Running tests&lt;/span&gt;
pytest -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deploy to production with the NEXUS AI CLI
&lt;/h2&gt;

&lt;p&gt;Your app is built and tested. Now get it live — no Dockerfile required.&lt;/p&gt;

&lt;p&gt;NEXUS AI detects your framework, builds the container for you, and deploys it. You push source code; NEXUS AI handles everything from there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 — Push source to GitHub
&lt;/h3&gt;

&lt;p&gt;Initialize a repo and push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"initial: document Q&amp;amp;A API"&lt;/span&gt;
gh repo create my-ai-app &lt;span class="nt"&gt;--public&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or push to an existing repo. The only requirement is that your &lt;code&gt;requirements.txt&lt;/code&gt; is at the project root — NEXUS AI uses it to detect that this is a Python app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6 — Install the NEXUS AI CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Linux&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://nexusai.run/install.sh | bash

&lt;span class="c"&gt;# macOS&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://nexusai.run/install-mac.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7 — Deploy from source
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Log in to NEXUS AI&lt;/span&gt;
nexus auth login

&lt;span class="c"&gt;# Deploy directly from your GitHub repo — no Docker required&lt;/span&gt;
nexus deploy &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/your-org/my-ai-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; doc-qa-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--port&lt;/span&gt; 8000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider&lt;/span&gt; gcp_cloud_run

&lt;span class="c"&gt;# Add the OpenAI key as an encrypted secret&lt;/span&gt;
nexus secret create OPENAI_API_KEY &lt;span class="nt"&gt;--deployment&lt;/span&gt; doc-qa-api

&lt;span class="c"&gt;# Attach a custom domain&lt;/span&gt;
nexus domain add api.yourcompany.com &lt;span class="nt"&gt;--deployment&lt;/span&gt; doc-qa-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NEXUS AI clones your repo, detects the Python/FastAPI framework, builds a production container image, and deploys it. Within 2–3 minutes you have a live URL with TLS and autoscaling. Stream logs to verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy logs doc-qa-api &lt;span class="nt"&gt;--follow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automate deploys with GitHub Actions
&lt;/h3&gt;

&lt;p&gt;Ask Claude Code to write the CI/CD config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;Write&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;GitHub&lt;/span&gt; &lt;span class="err"&gt;Actions&lt;/span&gt; &lt;span class="err"&gt;workflow&lt;/span&gt; &lt;span class="err"&gt;that&lt;/span&gt; &lt;span class="err"&gt;redeploys&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;NEXUS&lt;/span&gt; &lt;span class="err"&gt;AI&lt;/span&gt; &lt;span class="err"&gt;deployment&lt;/span&gt; &lt;span class="err"&gt;on&lt;/span&gt; &lt;span class="err"&gt;every&lt;/span&gt; &lt;span class="err"&gt;push&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;main.&lt;/span&gt;
&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s"&gt; Use NEXUSAI_TOKEN as a secret. The deployment name is doc-qa-api.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code generates a complete &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt;. The workflow calls &lt;code&gt;nexus deploy redeploy doc-qa-api&lt;/code&gt; — NEXUS AI pulls the latest source, rebuilds the container, and rolls it out. Every push to &lt;code&gt;main&lt;/code&gt; goes to production automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Advanced Claude Code patterns for AI development
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multi-file refactoring
&lt;/h3&gt;

&lt;p&gt;Claude Code handles refactors that would take hours manually. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; The document store is currently an in-memory dict. Refactor it to use Redis so documents
&amp;gt; persist across server restarts. Update all references, add redis to requirements.txt,
&amp;gt; and update the CLAUDE.md architecture section.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It updates &lt;code&gt;main.py&lt;/code&gt;, &lt;code&gt;requirements.txt&lt;/code&gt;, and &lt;code&gt;CLAUDE.md&lt;/code&gt; in one coherent pass — and since NEXUS AI builds from source, you just push the changes and redeploy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging without context-switching
&lt;/h3&gt;

&lt;p&gt;When something breaks in production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nexus deploy logs doc-qa-api &lt;span class="nt"&gt;--tail&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the error, paste it into Claude Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Getting this error in production logs: [paste error]
&amp;gt; Find the root cause and fix it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code reads the relevant code, identifies the issue, and applies the fix — all without you manually tracing through stack traces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Claude Code for code review
&lt;/h3&gt;

&lt;p&gt;Before opening a PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;&amp;gt; Review the changes in git diff HEAD~1 for:
&amp;gt; - Security issues (injection, hardcoded secrets, unsafe deserialization)
&amp;gt; - Missing input validation on the API endpoints
&amp;gt; - Performance issues in the chunking logic
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code runs the diff and produces a structured review with specific line references.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Claude Code mistakes to avoid
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Giving vague prompts.&lt;/strong&gt; "Make this better" produces mediocre output. "Refactor the chunking function to reduce memory allocation by processing tokens in a streaming fashion instead of loading the full document" produces a specific, actionable change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not using CLAUDE.md.&lt;/strong&gt; Without it, you re-explain your stack every session. Ten minutes setting it up saves hours over the life of a project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accepting the first output blindly.&lt;/strong&gt; Claude Code is fast, not infallible. Run the tests after every significant change. When they fail, let Claude Code fix them — that feedback loop is what makes it reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Letting it over-engineer.&lt;/strong&gt; Claude Code will sometimes propose abstractions you don't need. If you asked for a simple endpoint and got a three-layer architecture with an abstract repository pattern, push back: "Simplify this — no abstraction layers, just the endpoint and direct database calls."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not scoping the context.&lt;/strong&gt; In very large codebases, &lt;code&gt;claude&lt;/code&gt; in the root directory gives it the whole repo. For a focused change, navigate to the relevant subdirectory first. Smaller context = more precise output.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Claude Code work with languages other than Python?
&lt;/h3&gt;

&lt;p&gt;Yes. Claude Code works with any language — TypeScript, Go, Rust, Ruby, Java. The same patterns apply: scaffold with a prompt, run it, let Claude Code fix errors. The &lt;code&gt;CLAUDE.md&lt;/code&gt; approach works especially well in polyglot repos where you need to document which parts use which language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Claude Code safe to run on production codebases?
&lt;/h3&gt;

&lt;p&gt;Claude Code asks for confirmation before writing files or running commands. You control what it executes. For sensitive production repos, review the proposed changes before confirming — Claude Code shows you a diff before applying it. Never give it credentials directly; use environment variables and secrets managers.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is Claude Code different from GitHub Copilot?
&lt;/h3&gt;

&lt;p&gt;Copilot autocompletes individual lines and functions inside an editor. Claude Code operates at the project level in the terminal — it understands the full codebase, can run code, read test output, and make coordinated multi-file changes. They're complementary: Copilot for keystroke-level suggestions, Claude Code for larger tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use Claude Code without an Anthropic account?
&lt;/h3&gt;

&lt;p&gt;No. Claude Code requires an Anthropic API key or Claude.ai Pro/Max subscription. Usage via the API is billed based on token consumption. The claude.ai subscription tiers include a monthly usage allocation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the best way to handle large codebases?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;.claudeignore&lt;/code&gt; (same syntax as &lt;code&gt;.gitignore&lt;/code&gt;) to exclude directories that aren't relevant to your current task — &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;dist&lt;/code&gt;, &lt;code&gt;venv&lt;/code&gt;, build artifacts. This keeps Claude Code's context focused on what matters and reduces token usage.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you built
&lt;/h2&gt;

&lt;p&gt;Start to finish: a document Q&amp;amp;A API scaffolded by Claude Code, with chunked retrieval, pytest coverage, and a live deployment on NEXUS AI — all without writing a Dockerfile or touching a browser.&lt;/p&gt;

&lt;p&gt;That's AI-augmented development in practice. Claude Code handled the scaffolding, boilerplate, tests, and debugging loop. You handled the architecture decisions and product requirements. The result ships faster and has better test coverage than the same work done manually.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dev.to/docs"&gt;NEXUS AI CLI&lt;/a&gt; handles the deployment side of this workflow. Install it, run &lt;code&gt;nexus auth login&lt;/code&gt;, and your next Claude Code-built app is one command away from production.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>claudeai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Deploy OpenClaw in NEXUS AI</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sun, 29 Mar 2026 03:18:58 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/how-to-deploy-openclaw-in-nexus-ai-30j8</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/how-to-deploy-openclaw-in-nexus-ai-30j8</guid>
      <description>&lt;h2&gt;
  
  
  OpenClaw Personal AI Assistant Deployment
&lt;/h2&gt;

&lt;p&gt;OpenClaw&lt;br&gt;
is a lightweight AI coding gateway — Claude Code-compatible — exposes a secure token-authenticated endpoint. NEXUS AI makes deploying it entirely conversational: no YAML files, no Dockerfiles, no console wrestling. Just ask and it's live.&lt;/p&gt;

&lt;p&gt;This guide walks you through deploying OpenClaw on NEXUS AI step by step — covering provider selection, environment setup, connecting your CLI, and optional advanced configuration. By the end you'll have a live gateway you can connect Claude Code or any compatible AI coding tool to.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is OpenClaw?
&lt;/h2&gt;

&lt;p&gt;OpenClaw (alpine/openclaw:latest) is a minimal, production-ready AI gateway service designed to work with Claude Code and compatible clients. It exposes a single authenticated endpoint on port 18789, identified by a gateway token that's either auto-generated or supplied by you at deploy time.&lt;/p&gt;

&lt;p&gt;Once deployed, any Claude Code-compatible tool can point at your OpenClaw instance and authenticate with the token — giving you a self-hosted, cloud-native AI coding backend.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;A NEXUS AI account with at least one project configured The NEXUS AI MCP connector enabled in Claude — or API access to api.zollo.live/mcp A supported cloud provider account (for GCP, AWS, or Azure deployments) The OpenClaw CLI installed locally to connect after deployment Tip: You can also deploy OpenClaw entirely from within a Claude chat session if you have the NEXUS AI MCP connector enabled. No terminal required for the deploy itself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploying OpenClaw — step by step
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;01 Choose your provider &amp;amp; environment
NEXUS AI supports four deployment providers out of the box. For local development and testing, Docker is the fastest path. For production workloads, GCP Cloud Run offers the best cold-start performance and auto-scaling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🐳 Docker Best for local dev &amp;amp; CI&lt;/p&gt;

&lt;p&gt;☁️ GCP Cloud Run Serverless, auto-scales&lt;/p&gt;

&lt;p&gt;⚡ AWS ECS Fargate Full AWS ecosystem&lt;/p&gt;

&lt;p&gt;🔷 Azure Container Apps Enterprise &amp;amp; compliance&lt;/p&gt;

&lt;p&gt;Environments map to: DEVELOPMENT for local testing, STAGING for pre-production validation, and PRODUCTION for live traffic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;02 Trigger the deployment
Via the NEXUS AI MCP in Claude, call nexusai_deploy_openclaw with your provider and environment. A minimal invocation looks like this:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_openclaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;provider:    &lt;/span&gt;&lt;span class="s2"&gt;"gcp_cloud_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;environment: &lt;/span&gt;&lt;span class="s2"&gt;"PRODUCTION"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;name:        &lt;/span&gt;&lt;span class="s2"&gt;"openclaw-gateway"&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="sr"&gt;/ optional
)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you don't supply a gatewayToken, one is securely auto-generated for you. You can also pass in Claude API credentials (claudeApiKey, claudeWebCookie) if your gateway requires them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;03 Save your deployment credentials
After a successful deploy call, NEXUS AI returns:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Field Description Example id Deployment UUID 40693d12-… gatewayToken Auth token for CLI 6fb631a9d6… status Current state queued → running url Public endpoint Available once live Important: Copy your gatewayToken immediately — it's only returned once. Treat it like a password and store it in a secrets manager or your .env.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;04 Monitor deployment status
Deployments move from queued → provisioning → running. Check status anytime:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;deploymentId: &lt;/span&gt;&lt;span class="s2"&gt;"40693d12-0839-4821-aa3c-3621f12c74f4"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once status shows running, the url field will be populated with your public endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- 05 Connect via the OpenClaw CLI
Point your local tooling at the gateway by setting two environment variables:

## Set your gateway token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
shell&lt;br&gt;
export OPENCLAW_GATEWAY_TOKEN="6fb631a9d6c66c45cb3f5890886b14dc"&lt;/p&gt;

&lt;p&gt;Point CLI at your deployment URL&lt;br&gt;
export OPENCLAW_GATEWAY_URL="&lt;a href="https://your-deployment-url" rel="noopener noreferrer"&gt;https://your-deployment-url&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## Verify the connection
openclaw status
You should see a confirmation that the gateway is reachable and authenticated. Claude Code and any compatible AI coding client will now route through your self-hosted OpenClaw instance.

* Tip: For persistent config, add these exports to your .zshrc / .bashrc, or use a .env file with direnv.
Advanced configuration
Custom gateway token
If you want a predictable, rotatable token instead of an auto-generated one, pass it explicitly at deploy time:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
NEXUS AI MCP&lt;br&gt;
nexusai_deploy_openclaw(&lt;br&gt;
  provider:      "gcp_cloud_run",&lt;br&gt;
  environment:   "PRODUCTION",&lt;br&gt;
  gatewayToken:  "my-secure-token-from-vault"&lt;br&gt;
)&lt;br&gt;
Passing Claude credentials&lt;br&gt;
If your OpenClaw instance needs to authenticate directly with Anthropic, you can pass your Claude session credentials at deploy time via claudeApiKey, claudeWebCookie, or claudeWebSessionKey. These are stored securely in NEXUS AI's secrets system and injected into the container at runtime.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scaling your deployment
&lt;/h2&gt;

&lt;p&gt;Once your OpenClaw gateway is live, you can scale it up instantly via NEXUS AI without redeploying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nexusai_deploy_scale(
  deploymentId: "40693d12-…",
  replicas:     3
)```


## Custom domain
Attach a custom domain to your OpenClaw gateway for a clean, branded endpoint:
NEXUS AI MCP nexusai_domains_add( deploymentId: "40693d12-…", domain: "openclaw.yourdomain.com" )

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Managing your OpenClaw deployment
&lt;/h1&gt;

&lt;p&gt;NEXUS AI gives you full lifecycle control over every deployment. Here's a quick reference:&lt;/p&gt;

&lt;p&gt;Action MCP Tool When to use Check status nexusai_deploy_status After deploying, or to verify health View logs nexusai_deploy_logs Debug connection or auth issues Stop gateway nexusai_deploy_stop Pause to save compute costs Restart nexusai_deploy_start After a stop, or after config changes Rollback nexusai_deploy_rollback Revert to a previous revision Delete nexusai_deploy_delete Permanently tear down&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Gateway stuck in "queued" Check that your cloud provider credentials are properly configured in NEXUS AI. For GCP, ensure your service account has Cloud Run admin permissions. Use nexusai_deploy_logs to see what's happening inside the container.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI returns 401 Unauthorized&lt;br&gt;
Double-check your OPENCLAW_GATEWAY_TOKEN environment variable. Tokens are case-sensitive. If you've lost the token, delete the deployment and redeploy with a custom gatewayToken you control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connection refused on port 18789&lt;br&gt;
Verify the deployment status is running (not queued or stopped). Also confirm your OPENCLAW_GATEWAY_URL includes the correct port and protocol.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;OpenClaw on NEXUS AI gives you a fully managed, cloud-native AI coding gateway without any of the infrastructure overhead. You get auto-generated tokens, multi-cloud flexibility, instant scaling, and full lifecycle management — all through natural language or a single API call.&lt;/p&gt;

&lt;p&gt;From here, you can explore connecting multiple Claude Code clients to the same gateway, attaching a custom domain, or setting up a staging → production promotion workflow entirely within NEXUS AI.&lt;/p&gt;

&lt;p&gt;Try it now: Head to &lt;a href="https://nexusai.run/" rel="noopener noreferrer"&gt;https://nexusai.run/&lt;/a&gt;. and enable the NEXUS AI MCP connector in Claude to deploy your first OpenClaw gateway in under 2 minutes.&lt;/p&gt;

&lt;h1&gt;
  
  
  AI #Deployment #OpenClaw
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>openclaw</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Deploy OpenClaw in NEXUS AI</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sun, 29 Mar 2026 03:18:58 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/how-to-deploy-openclaw-in-nexus-ai-5648</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/how-to-deploy-openclaw-in-nexus-ai-5648</guid>
      <description>&lt;h2&gt;
  
  
  OpenClaw Personal AI Assistant Deployment
&lt;/h2&gt;

&lt;p&gt;OpenClaw&lt;br&gt;
is a lightweight AI coding gateway — Claude Code-compatible — exposes a secure token-authenticated endpoint. NEXUS AI makes deploying it entirely conversational: no YAML files, no Dockerfiles, no console wrestling. Just ask and it's live.&lt;/p&gt;

&lt;p&gt;This guide walks you through deploying OpenClaw on NEXUS AI step by step — covering provider selection, environment setup, connecting your CLI, and optional advanced configuration. By the end you'll have a live gateway you can connect Claude Code or any compatible AI coding tool to.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is OpenClaw?
&lt;/h2&gt;

&lt;p&gt;OpenClaw (alpine/openclaw:latest) is a minimal, production-ready AI gateway service designed to work with Claude Code and compatible clients. It exposes a single authenticated endpoint on port 18789, identified by a gateway token that's either auto-generated or supplied by you at deploy time.&lt;/p&gt;

&lt;p&gt;Once deployed, any Claude Code-compatible tool can point at your OpenClaw instance and authenticate with the token — giving you a self-hosted, cloud-native AI coding backend.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;A NEXUS AI account with at least one project configured The NEXUS AI MCP connector enabled in Claude — or API access to api.zollo.live/mcp A supported cloud provider account (for GCP, AWS, or Azure deployments) The OpenClaw CLI installed locally to connect after deployment Tip: You can also deploy OpenClaw entirely from within a Claude chat session if you have the NEXUS AI MCP connector enabled. No terminal required for the deploy itself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploying OpenClaw — step by step
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;01 Choose your provider &amp;amp; environment
NEXUS AI supports four deployment providers out of the box. For local development and testing, Docker is the fastest path. For production workloads, GCP Cloud Run offers the best cold-start performance and auto-scaling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🐳 Docker Best for local dev &amp;amp; CI&lt;/p&gt;

&lt;p&gt;☁️ GCP Cloud Run Serverless, auto-scales&lt;/p&gt;

&lt;p&gt;⚡ AWS ECS Fargate Full AWS ecosystem&lt;/p&gt;

&lt;p&gt;🔷 Azure Container Apps Enterprise &amp;amp; compliance&lt;/p&gt;

&lt;p&gt;Environments map to: DEVELOPMENT for local testing, STAGING for pre-production validation, and PRODUCTION for live traffic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;02 Trigger the deployment
Via the NEXUS AI MCP in Claude, call nexusai_deploy_openclaw with your provider and environment. A minimal invocation looks like this:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_openclaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;provider:    &lt;/span&gt;&lt;span class="s2"&gt;"gcp_cloud_run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;environment: &lt;/span&gt;&lt;span class="s2"&gt;"PRODUCTION"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;name:        &lt;/span&gt;&lt;span class="s2"&gt;"openclaw-gateway"&lt;/span&gt;  &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="sr"&gt;/ optional
)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you don't supply a gatewayToken, one is securely auto-generated for you. You can also pass in Claude API credentials (claudeApiKey, claudeWebCookie) if your gateway requires them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;03 Save your deployment credentials
After a successful deploy call, NEXUS AI returns:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Field Description Example id Deployment UUID 40693d12-… gatewayToken Auth token for CLI 6fb631a9d6… status Current state queued → running url Public endpoint Available once live Important: Copy your gatewayToken immediately — it's only returned once. Treat it like a password and store it in a secrets manager or your .env.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;04 Monitor deployment status
Deployments move from queued → provisioning → running. Check status anytime:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;nexusai_deploy_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="ss"&gt;deploymentId: &lt;/span&gt;&lt;span class="s2"&gt;"40693d12-0839-4821-aa3c-3621f12c74f4"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once status shows running, the url field will be populated with your public endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- 05 Connect via the OpenClaw CLI
Point your local tooling at the gateway by setting two environment variables:

## Set your gateway token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
shell&lt;br&gt;
export OPENCLAW_GATEWAY_TOKEN="6fb631a9d6c66c45cb3f5890886b14dc"&lt;/p&gt;

&lt;p&gt;Point CLI at your deployment URL&lt;br&gt;
export OPENCLAW_GATEWAY_URL="&lt;a href="https://your-deployment-url" rel="noopener noreferrer"&gt;https://your-deployment-url&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## Verify the connection
openclaw status
You should see a confirmation that the gateway is reachable and authenticated. Claude Code and any compatible AI coding client will now route through your self-hosted OpenClaw instance.

* Tip: For persistent config, add these exports to your .zshrc / .bashrc, or use a .env file with direnv.
Advanced configuration
Custom gateway token
If you want a predictable, rotatable token instead of an auto-generated one, pass it explicitly at deploy time:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
NEXUS AI MCP&lt;br&gt;
nexusai_deploy_openclaw(&lt;br&gt;
  provider:      "gcp_cloud_run",&lt;br&gt;
  environment:   "PRODUCTION",&lt;br&gt;
  gatewayToken:  "my-secure-token-from-vault"&lt;br&gt;
)&lt;br&gt;
Passing Claude credentials&lt;br&gt;
If your OpenClaw instance needs to authenticate directly with Anthropic, you can pass your Claude session credentials at deploy time via claudeApiKey, claudeWebCookie, or claudeWebSessionKey. These are stored securely in NEXUS AI's secrets system and injected into the container at runtime.&lt;/p&gt;
&lt;h2&gt;
  
  
  Scaling your deployment
&lt;/h2&gt;

&lt;p&gt;Once your OpenClaw gateway is live, you can scale it up instantly via NEXUS AI without redeploying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nexusai_deploy_scale(
  deploymentId: "40693d12-…",
  replicas:     3
)```


## Custom domain
Attach a custom domain to your OpenClaw gateway for a clean, branded endpoint:
NEXUS AI MCP nexusai_domains_add( deploymentId: "40693d12-…", domain: "openclaw.yourdomain.com" )

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Managing your OpenClaw deployment
&lt;/h1&gt;

&lt;p&gt;NEXUS AI gives you full lifecycle control over every deployment. Here's a quick reference:&lt;/p&gt;

&lt;p&gt;Action MCP Tool When to use Check status nexusai_deploy_status After deploying, or to verify health View logs nexusai_deploy_logs Debug connection or auth issues Stop gateway nexusai_deploy_stop Pause to save compute costs Restart nexusai_deploy_start After a stop, or after config changes Rollback nexusai_deploy_rollback Revert to a previous revision Delete nexusai_deploy_delete Permanently tear down&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Gateway stuck in "queued" Check that your cloud provider credentials are properly configured in NEXUS AI. For GCP, ensure your service account has Cloud Run admin permissions. Use nexusai_deploy_logs to see what's happening inside the container.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CLI returns 401 Unauthorized&lt;br&gt;
Double-check your OPENCLAW_GATEWAY_TOKEN environment variable. Tokens are case-sensitive. If you've lost the token, delete the deployment and redeploy with a custom gatewayToken you control.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connection refused on port 18789&lt;br&gt;
Verify the deployment status is running (not queued or stopped). Also confirm your OPENCLAW_GATEWAY_URL includes the correct port and protocol.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;OpenClaw on NEXUS AI gives you a fully managed, cloud-native AI coding gateway without any of the infrastructure overhead. You get auto-generated tokens, multi-cloud flexibility, instant scaling, and full lifecycle management — all through natural language or a single API call.&lt;/p&gt;

&lt;p&gt;From here, you can explore connecting multiple Claude Code clients to the same gateway, attaching a custom domain, or setting up a staging → production promotion workflow entirely within NEXUS AI.&lt;/p&gt;

&lt;p&gt;Try it now: Head to &lt;a href="https://nexusai.run/" rel="noopener noreferrer"&gt;https://nexusai.run/&lt;/a&gt;. and enable the NEXUS AI MCP connector in Claude to deploy your first OpenClaw gateway in under 2 minutes.&lt;/p&gt;

&lt;h1&gt;
  
  
  AI #Deployment #OpenClaw
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>openclaw</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Deploy an AI App in Production: The Complete 2026 Guide</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Sun, 29 Mar 2026 02:25:42 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/how-to-deploy-an-ai-app-in-production-the-complete-2026-guide-3i0g</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/how-to-deploy-an-ai-app-in-production-the-complete-2026-guide-3i0g</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Deploying applications shouldn’t be this hard.&lt;/p&gt;

&lt;p&gt;If you’ve ever tried to deploy an app, you’ve probably dealt with:&lt;/p&gt;

&lt;p&gt;YAML configuration files&lt;/p&gt;

&lt;p&gt;CI/CD pipelines&lt;/p&gt;

&lt;p&gt;Infrastructure setup&lt;/p&gt;

&lt;p&gt;Debugging deployment failures&lt;/p&gt;

&lt;p&gt;What starts as “just a quick deploy” often turns into hours of frustration.&lt;/p&gt;

&lt;p&gt;But what if you could deploy an app using AI — just by describing what you want?&lt;/p&gt;

&lt;p&gt;That’s exactly what platforms like NEXUS AI are making possible.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn how to deploy apps with AI step by step, and why this is becoming the future of software development.&lt;/p&gt;

&lt;h1&gt;
  
  
  🤖 What is AI-Powered Deployment?
&lt;/h1&gt;

&lt;p&gt;AI-powered deployment allows developers to:&lt;/p&gt;

&lt;p&gt;Deploy applications using natural language prompts&lt;/p&gt;

&lt;p&gt;Automate infrastructure setup&lt;/p&gt;

&lt;p&gt;Eliminate manual DevOps work&lt;/p&gt;

&lt;p&gt;Fix issues automatically using AI&lt;/p&gt;

&lt;p&gt;Instead of writing complex configuration files, you simply tell the system what you want.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@nexus ai deploy my Node.js app to production&lt;/code&gt;&lt;br&gt;
And the platform handles:&lt;/p&gt;

&lt;p&gt;Build&lt;/p&gt;

&lt;p&gt;Containerization&lt;/p&gt;

&lt;p&gt;Deployment&lt;/p&gt;

&lt;p&gt;Scaling&lt;/p&gt;

&lt;p&gt;😩 Why Traditional Deployment is So Difficult&lt;br&gt;
Before we dive into AI deployment, let’s understand the problem.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Too Many Tools
&lt;/h1&gt;

&lt;p&gt;Developers often need:&lt;/p&gt;

&lt;p&gt;Docker&lt;/p&gt;

&lt;p&gt;Kubernetes&lt;/p&gt;

&lt;p&gt;CI/CD pipelines&lt;/p&gt;

&lt;p&gt;Cloud providers&lt;/p&gt;

&lt;h1&gt;
  
  
  2. YAML Complexity
&lt;/h1&gt;

&lt;p&gt;Even a small mistake in YAML can break your deployment.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;version: '3'&lt;br&gt;
services:&lt;br&gt;
 app:&lt;br&gt;
   build: .&lt;br&gt;
   ports:&lt;br&gt;
     - "3000:3000"&lt;/code&gt;&lt;br&gt;
One indentation error → everything fails.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Debugging is Painful
&lt;/h1&gt;

&lt;p&gt;Common issues:&lt;/p&gt;

&lt;p&gt;Build failures&lt;/p&gt;

&lt;p&gt;Environment mismatches&lt;/p&gt;

&lt;p&gt;Missing dependencies&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Requires DevOps Knowledge
&lt;/h1&gt;

&lt;p&gt;Not every developer is a DevOps expert.&lt;/p&gt;

&lt;h1&gt;
  
  
  🚀 How AI Changes Deployment
&lt;/h1&gt;

&lt;p&gt;AI removes complexity by handling everything automatically.&lt;/p&gt;

&lt;h1&gt;
  
  
  With NEXUS AI:
&lt;/h1&gt;

&lt;p&gt;👉 You don’t configure infrastructure&lt;br&gt;
👉 You don’t write YAML&lt;br&gt;
👉 You don’t debug pipelines manually&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;p&gt;Prompt → AI → Live App&lt;/p&gt;

&lt;h1&gt;
  
  
  ⚡ Step-by-Step: Deploy an App with AI
&lt;/h1&gt;

&lt;p&gt;Let’s walk through how it works.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Install NEXUS AI CLI
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;npm install -g nexusapp-cli&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Login
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;nexus auth login&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Deploy Your App
&lt;/h1&gt;

&lt;p&gt;Now the magic happens.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@nexus deploy my app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@nexus deploy my Node.js API to production on gcp cloud provider&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: AI Handles Everything
&lt;/h1&gt;

&lt;p&gt;Behind the scenes, NEXUS AI:&lt;/p&gt;

&lt;p&gt;Detects your app type&lt;/p&gt;

&lt;p&gt;Builds your container&lt;/p&gt;

&lt;p&gt;Configures infrastructure&lt;/p&gt;

&lt;p&gt;Deploys to cloud&lt;/p&gt;

&lt;p&gt;Makes your app live&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Your App is Live 🚀
&lt;/h1&gt;

&lt;p&gt;In minutes, your app is deployed — no manual setup required.&lt;/p&gt;

&lt;h1&gt;
  
  
  💬 Bonus: AI Support &amp;amp; Troubleshooting
&lt;/h1&gt;

&lt;p&gt;One of the biggest advantages is AI-powered support.&lt;/p&gt;

&lt;p&gt;If something breaks:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@nexus fix my deployment issue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;NEXUS AI will:&lt;/p&gt;

&lt;p&gt;Diagnose the problem&lt;/p&gt;

&lt;p&gt;Suggest fixes&lt;/p&gt;

&lt;h1&gt;
  
  
  Apply solutions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  🔥 Real Use Cases
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Indie Developers&lt;br&gt;
Launch projects quickly without DevOps knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Startups&lt;br&gt;
Reduce time to production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Teams&lt;br&gt;
Simplify deployment workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Beginners&lt;br&gt;
Deploy apps without learning complex tools.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  🧠 Why This is the Future
&lt;/h1&gt;

&lt;p&gt;We’ve already seen this shift:&lt;/p&gt;

&lt;p&gt;Writing code → AI-assisted coding&lt;/p&gt;

&lt;p&gt;Debugging → AI debugging&lt;/p&gt;

&lt;h1&gt;
  
  
  Now → Deployment is next
&lt;/h1&gt;

&lt;p&gt;AI is turning complex workflows into simple interactions.&lt;/p&gt;

&lt;h1&gt;
  
  
  🚀 Key Benefits of NexusAI
&lt;/h1&gt;

&lt;p&gt;Faster deployment&lt;/p&gt;

&lt;p&gt;Less complexity&lt;/p&gt;

&lt;p&gt;AI-powered troubleshooting&lt;/p&gt;

&lt;p&gt;Works with prompts, code, or Git&lt;/p&gt;

&lt;p&gt;No DevOps expertise required&lt;/p&gt;

&lt;h1&gt;
  
  
  💡 Pro Tips for Using AI Deployment
&lt;/h1&gt;

&lt;p&gt;Be clear in your prompts&lt;/p&gt;

&lt;p&gt;Use Git integration for real projects&lt;/p&gt;

&lt;p&gt;Let AI handle infrastructure&lt;/p&gt;

&lt;p&gt;Use CLI for faster workflows&lt;/p&gt;

&lt;h1&gt;
  
  
  🔮 Final Thoughts
&lt;/h1&gt;

&lt;p&gt;The way we deploy applications is changing.&lt;/p&gt;

&lt;p&gt;Instead of spending hours configuring infrastructure, developers can now:&lt;/p&gt;

&lt;p&gt;👉 Describe what they want&lt;br&gt;
👉 Let AI handle the rest&lt;/p&gt;

&lt;p&gt;NexusAI is helping lead this shift toward AI-native development workflows.&lt;/p&gt;

&lt;p&gt;👉 Get Started&lt;br&gt;
Try NEXUS AII and deploy your first app in minutes:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://nexusai.run" rel="noopener noreferrer"&gt;https://nexusai.run&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>automation</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Run your Docker container from AI prompts</title>
      <dc:creator>Saif Ali</dc:creator>
      <pubDate>Thu, 26 Feb 2026 15:22:00 +0000</pubDate>
      <link>https://forem.com/sali_ac161a1b71406354896c/run-your-docker-container-from-ai-prompts-188b</link>
      <guid>https://forem.com/sali_ac161a1b71406354896c/run-your-docker-container-from-ai-prompts-188b</guid>
      <description>&lt;h2&gt;
  
  
  What is NEXUS AI?
&lt;/h2&gt;

&lt;p&gt;If AI can write code and generate images, it can also manage infrastructure. &lt;/p&gt;

&lt;h2&gt;
  
  
  How it Works
&lt;/h2&gt;

&lt;p&gt;With NEXUS AI, infrastructure becomes conversational...&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>automation</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
