Release Flags
Release flags let you ship code before you release its behavior. A flag belongs to one app in one environment, so a production rollout cannot accidentally change staging or another app in the same project.
Slipway keeps the contract deliberately small:
- a master switch that acts as an immediate kill switch;
- a stable percentage rollout from 0–100%;
- an optional typed allowlist for users, accounts, tenants, or teams;
- request telemetry in Lookout, split by flag on and off.
There are no variants or nested rule builders. A flag always evaluates to a boolean.
Create a flag
Open an app, expand Release flags, enter a lowercase key such as new-checkout, and select Add. New flags start off with a 0% rollout, so creating one cannot expose unfinished behavior.
Use the switch to release or kill the flag. Use the ellipsis menu to set its description, percentage, and allowlist.
Allowlist entries are typed, one per line:
user:42
account:acme
tenant:north
team:staffThe master switch must be on before either the percentage or allowlist can return true.
Evaluate a flag in Sails
Install the Slipway hook in the deployed application:
npm install sails-hook-slipwayThen evaluate the flag from an action, helper, policy, or hook:
const useNewCheckout = await sails.helpers.flags.enabled.with({
key: 'new-checkout',
req: this.req,
defaultValue: false
})
if (useNewCheckout) {
// Run the new behavior.
}flags.enabled is a regular Sails helper machine. The hook waits for the built-in helpers hook and furnishes the helper through the same Sails API used by hooks such as sails-hook-mail. Sails therefore validates the declared key, req, context, and defaultValue inputs before flag evaluation runs. If the application already defines sails.helpers.flags.enabled, Slipway keeps the application-owned helper and logs a warning instead of replacing it.
Always choose the default explicitly. Slipway returns that value when the flag is unknown or the control plane has never been reachable. Flag evaluation does not make the application request fail.
For work without an HTTP request, supply the stable context yourself:
const enabled = await sails.helpers.flags.enabled.with({
key: 'new-checkout',
context: {
account: invoice.account,
user: invoice.owner
},
defaultValue: false
})For an Inertia page, evaluate on the server and share only the boolean result:
return {
page: 'checkout/show',
props: {
useNewCheckout: await sails.helpers.flags.enabled.with({
key: 'new-checkout',
req: this.req,
defaultValue: false
})
}
}<NewCheckout v-if="useNewCheckout" />
<CurrentCheckout v-else />The browser receives no flag credential or rule list.
With req, the hook looks for user, account, tenant, team, and session identifiers in the request identity and session. An explicit context takes precedence.
Evaluation order
Slipway evaluates a flag in this order:
- An off master switch returns
false. - A matching typed allowlist entry returns
true. - A 100% rollout returns
true; a 0% rollout returnsfalse. - A partial rollout hashes the first stable user, account, tenant, team, or session identifier.
- A partial rollout without stable context returns
false.
The hash is deterministic. The same identity stays in the same cohort as the percentage moves, rather than randomly changing on every request.
Changes without redeploying
The hook caches the last valid flag configuration and refreshes it in the background every 15 seconds by default. A switch, percentage, or allowlist change therefore reaches a running app without a new deployment. If Slipway is temporarily unavailable, the hook continues using its last valid snapshot.
You can tune the cache in config/slipway.js:
module.exports.slipway = {
flags: {
enabled: true,
refreshInterval: 15000,
requestTimeout: 3000
}
}Slipway injects the private flag endpoint and environment credential during a normal deployment and a rollback. Do not expose SLIPWAY_FLAGS_TOKEN to browser code. Existing apps need one deployment after upgrading Slipway and sails-hook-slipway; flag changes after that do not require redeploying.
Measure the rollout in Lookout
When a request evaluates a flag, the hook attaches the boolean result to that request span. In Lookout → Requests, Slipway compares the request count, average latency, 5xx error rate, and trace-linked exceptions for the on and off cohorts. Individual request details also show the evaluated flag values.
The comparison only appears when requests have evaluated a flag. Applications that do not use release flags get the same Lookout interface as before.
Safe rollout sequence
A practical production rollout is:
- Deploy the new code with
defaultValue: false. - Create the flag off and verify the old path.
- Allowlist the team or a test account.
- Move through a small percentage, then 25%, 50%, and 100% while watching Lookout.
- Turn the switch off immediately if errors or latency regress.
- After the new path is stable, remove the old path and then delete the flag.
Release flags reduce rollout risk; they do not replace database compatibility. Keep schema changes backward-compatible while old and new code can both run.