Environment configuration
New workspaces start with Sandbox and Live. Seamward creates both with the workspace. Users do not add, rename, or delete environments. Existing workspaces retain their Development, Staging, and Production records until reviewed migration. Setup authorization selects an existing environment; it does not create Staging. Automation can discover exact targets through the workspace environment API.
Environment model
Optional local credential saving
The automatic setup guide describes the alpha
seamward setup credentials terminal wizard. Agent MCP cannot read or save these
files, including through direct tool calls. Its internal CLI review/save services operate only
with Sandbox authorization or an exact existing Development grant and a user-selected root .env or .env.local
file. Saving does not require a startup loader. You are responsible for loading
that file when starting the application. A filename alone does not establish the deployment environment.
After saving, the CLI checks every saved Connection key and ingest token against Seamward. Repeat this read-only check at any time:
Code example
seamward setup verifyIt checks the selected file, not shell overrides or retained login credentials.
CONNECTION VERIFIED means every expected Integration and environment matched
at check time. It does not start the app, send observations or persist a success
receipt. A failed check leaves saved credentials intact and exits 1.
Saving is opt-in and does not configure Live or legacy Production or Staging. Files contain
plaintext secrets, even with owner-only permissions. Keep them out of Git,
recordings and shared backups. Before modifying an existing file, the tool saves
an owner-only timestamped backup in your user account's .seamward-runtime-backups
directory. Recovery is manual: review the backup privately before restoring it,
because old tokens may have been revoked. Do not edit the file while saving.
These protections cannot defend against malicious software running as your user.
Git-ignored files are discoverable; ignoring a file does not hide it from this
wizard. Existing matching credentials must have owner-only permissions. Refused
permissions require an explicit local correction, not automatic permission changes.
Temporary plaintext is staged in that private directory outside Git, not inside
the project. Atomic saving requires both locations to share a filesystem;
otherwise it fails without changing the target. A hard crash may leave a private
pending.env there. Confirm no save is active before removing an orphan privately.
Successfully saving a file does not prove that your running application loaded it or sent observations. Start your application normally with that file loaded and confirm actual observations.
Explicit startup diagnostic
This is not required for onboarding. If you specifically request an automated
startup test, the reviewed saved runtime mode starts the normal command without
injected Seamward credentials and requires observations from fresh synthetic
traffic. It reads but does not modify the approved local file. Its receipt proves
the last reviewed run, not a deployed environment or ongoing service health.
An Integration belongs to the workspace. Each environment has an independent connection for that Integration:
Code example
Workspace -> Integrations -> Sandbox connection -> Live connectionFor example, Candidate ATS and Billing webhooks are separate Integrations. Each can have independent Sandbox and Live credentials without duplicating its business identity. Use the Test mode switch in the console header: off and gray selects testing, and on and blue selects Live. Testing pages show a bright amber Test mode banner with dark text at the top of the screen, above the sidebar and header. The banner names the selected environment and stays visible while you scroll. The dashboard, Integrations, observations, and incidents follow that environment. Notifications and workspace settings remain shared across modes.
During the compatibility migration, Development and Staging are testing environments, and Production is Live. Existing Staging links keep their exact environment. Entering testing selects Sandbox when available, then Development, then Staging; the console remembers the last testing environment for each workspace. Selecting a mode does not change configuration, credentials, or your plan allowance.
The selected environment stays in the URL so a shared link opens the same context. Switching from an integration, observation, or incident detail opens the corresponding list in the destination mode. Unsaved form changes require a discard confirmation; switching is unavailable while an action is running or when the destination environment is missing. A full-page progress animation covers the current view while the destination loads. The control and data change together when loading finishes. With reduced motion enabled, the progress indicator stays still.
Required values
Each connection owns two runtime values:
Code example
SEAMWARD_CONNECTION_KEY=sw_conn_v1.replace_meSEAMWARD_INGEST_TOKEN=sw_ing_replace_me| Variable | Purpose | Secret? |
|---|---|---|
SEAMWARD_CONNECTION_KEY | Routes observations to one Integration in its workspace environment | No |
SEAMWARD_INGEST_TOKEN | Authenticates and signs writes for that Integration | Yes; secret store only |
SEAMWARD_INGEST_URL | Overrides the default endpoint (https://api.seamward.com/ingest) for custom or self-hosted deployments | No |
Copy both values from the Integration's Collector setup tab. The token is shown only when issued or rotated. Automatic setup stores it outside the repository in a protected local credential store and reports the environment variable name your deployment needs.
Release context
Deployment metadata links changes to a release. Set it explicitly:
Code example
deployment: { service: "candidate-api", release: process.env.RELEASE_VERSION, commitSha: process.env.GITHUB_SHA,}The Node.js and framework-neutral PHP collectors also recognize SEAMWARD_SERVICE, SEAMWARD_RELEASE,
SEAMWARD_COMMIT_SHA, VERCEL_GIT_COMMIT_SHA, RENDER_GIT_COMMIT,
RAILWAY_GIT_COMMIT_SHA, and GITHUB_SHA. Invalid values are ignored instead
of breaking the host application. Laravel's published configuration resolves the same known values while configuration is loaded, so cached configuration remains deterministic. See release metadata
for deployment recipes.
Environment separation
Every Integration has a Sandbox connection for testing and a separate Live connection for production traffic from the moment you add it. There is nothing to set up for the second mode. Copied contracts start as drafts and copied rules are disabled. Credentials, baselines, observations, incidents, and approval history are not copied. Existing connections are not overwritten by this flow.
Each connection has its own Connection key, ingest token, baselines, and incidents:
- Sandbox traffic never changes Live baselines.
- Rotating a Sandbox connection's token cannot interrupt Live delivery.
- An incident's environment comes from the authenticated Integration, not from caller-supplied payload data.
- Revoking one connection's token stops only that observation boundary.
Never reuse a Live connection's token in local or testing deployments. Existing legacy Development, Staging, and Production connections retain their exact credentials and evidence until reviewed migration. Account management CLI mode flags are removed; complete the reviewed workspace conversion before using canonical connection commands.
The runtime does not need SEAMWARD_ENVIRONMENT. The authenticated Connection
key and ingest token select the correct environment. A production deployment
therefore needs only the exact generated Connection-key and ingest-token
variables expected by your instrumentation. Obtain the pair from that connection's Collector setup in the dashboard and place it directly in the hosting platform's secret manager. Management CLI commands do not read application .env files or issue, rotate, recover or export Live ingest secrets.
One token for every Integration
Your application does not need a key and token for each Integration. A workspace has one ingest token per mode, and each Integration has a short, fixed connection name your code uses.
- Switch the console to the mode you are setting up, Test or Live.
- Open Settings, then Ingest token, and select Issue token. The token is shown once. Store it as
SEAMWARD_INGEST_TOKENin the environment that runs in that mode. - Open an Integration and select Collector setup. Copy its connection name, for example
paystack-webhook, and the example for your stack.
Code example
SEAMWARD_INGEST_TOKEN=sw_svc_v1.replace_with_ingest_tokenYour code names each Integration and shares the token:
Code example
import { createSeamwardService } from "@seamward/collector";
const seamward = createSeamwardService({ ingestToken: process.env.SEAMWARD_INGEST_TOKEN!,});
export const paystackWebhook = seamward.connection("paystack-webhook");export const crawlerApi = seamward.connection("crawler-api");Code example
// config/seamward.php (Laravel)'ingest_token' => env('SEAMWARD_INGEST_TOKEN'),'connections' => [ 'paystack-webhook' => 'paystack-webhook', 'crawler-api' => 'crawler-api',],Seamward creates the connection name from the Integration's name when you add it. It is unique in the workspace, the same in Test and Live, and never changes, so renaming an Integration does not break your code. It is an identifier, not a secret.
The token decides the mode: a Test token records into each Integration's Sandbox connection and a Live token into its Live connection. Moving to production changes one environment variable.
| Situation | What happens |
|---|---|
| No Integration in the workspace has that name | The batch is rejected with 401 |
| The token was revoked, or its overlap ended | The batch is rejected with 401 |
| A limited extra service does not list it | The batch is rejected with 401. Collector setup names the services that cannot send there |
Rotate or revoke the token
Select Rotate and choose an overlap. The current token keeps working for that long, 24 hours by default and at most 7 days, so you can deploy the new one first. There are at most two working tokens per mode.
Revoke stops a token immediately. If it leaked, Discard what it wrote removes the observations that token recorded between two times and re-analyses the affected connections, so traffic sent with a stolen token does not stay in your baselines.
An ingest token can only write observations. It cannot read evidence or change configuration. Seamward stores a hash of it, never the token.
Extra services
Most workspaces need only the workspace token. If a second application sends to the same workspace, Add service under Extra services gives it its own token in each mode. You can rotate or revoke that token without touching the first application, and you can limit the service to specific Integrations so its token is refused everywhere else. Deleting an extra service stops its tokens immediately.
Connection keys with their own ingest tokens are still accepted by the ingest API.
Next steps
- Configuration reference: every option, format, and default.
- Node.js collector setup: use the published ESM package.
- Laravel collector setup: configure named connections with the alpha package.
- PHP collector setup: build on the framework-neutral alpha core.
Manage an existing connection
Contracts and rules are written once for an Integration: a contract version you register appears in both modes as a draft, and a rule you create appears in the other mode switched off. You activate a version and switch a rule on in each mode separately. The Contracts and Rules tabs show where each stands in the other mode.
To start one mode again from empty, open the Integration's Overview in that mode and choose Clear Test data or Clear Live data in the Danger zone. It removes that mode's observations, detected changes and incidents after a review, and leaves the other mode alone. Contract versions return as drafts and rules return switched off. Whole-Integration deletion in the same place removes both modes.
See Sandbox limits and account usage before sending test traffic.
