@probelabs/visor 0.1.130 → 0.1.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/defaults/visor.yaml +5 -2
- package/dist/ai-review-service.d.ts +2 -0
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config/cli-handler.d.ts +5 -0
- package/dist/config/cli-handler.d.ts.map +1 -0
- package/dist/config/config-reloader.d.ts +24 -0
- package/dist/config/config-reloader.d.ts.map +1 -0
- package/dist/config/config-snapshot-store.d.ts +21 -0
- package/dist/config/config-snapshot-store.d.ts.map +1 -0
- package/dist/config/config-watcher.d.ts +19 -0
- package/dist/config/config-watcher.d.ts.map +1 -0
- package/dist/config/types.d.ts +16 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/defaults/visor.yaml +5 -2
- package/dist/docs/ai-configuration.md +139 -0
- package/dist/docs/ai-custom-tools.md +30 -0
- package/dist/docs/capacity-planning.md +359 -0
- package/dist/docs/commands.md +35 -0
- package/dist/docs/database-operations.md +487 -0
- package/dist/docs/index.md +6 -1
- package/dist/docs/licensing.md +372 -0
- package/dist/docs/production-deployment.md +583 -0
- package/dist/examples/ai-with-bash.yaml +17 -0
- package/dist/generated/config-schema.d.ts +4 -0
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/index.js +9945 -10907
- package/dist/liquid-extensions.d.ts +7 -0
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/output/traces/{run-2026-02-11T16-20-59-999Z.ndjson → run-2026-02-15T19-14-20-379Z.ndjson} +84 -84
- package/dist/{traces/run-2026-02-11T16-21-47-711Z.ndjson → output/traces/run-2026-02-15T19-15-09-410Z.ndjson} +1019 -1019
- package/dist/providers/ai-check-provider.d.ts +5 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/sdk/{check-provider-registry-PANIXYRB.mjs → check-provider-registry-AAPPJ4CP.mjs} +7 -7
- package/dist/sdk/{check-provider-registry-M3Y6JMTW.mjs → check-provider-registry-S7BMQ2FC.mjs} +7 -7
- package/dist/sdk/check-provider-registry-ZOLEYDKM.mjs +28 -0
- package/dist/sdk/{chunk-VMLORODQ.mjs → chunk-2GCSK3PD.mjs} +4 -4
- package/dist/sdk/{chunk-EUUAQBTW.mjs → chunk-6ZZ4DPAA.mjs} +240 -48
- package/dist/sdk/chunk-6ZZ4DPAA.mjs.map +1 -0
- package/dist/sdk/{chunk-HOKQOO3G.mjs → chunk-EBTD2D4L.mjs} +2 -2
- package/dist/sdk/chunk-LDFUW34H.mjs +39912 -0
- package/dist/sdk/chunk-LDFUW34H.mjs.map +1 -0
- package/dist/sdk/{chunk-UCNT3PDT.mjs → chunk-LQ5B4T6L.mjs} +5 -1
- package/dist/sdk/chunk-LQ5B4T6L.mjs.map +1 -0
- package/dist/sdk/{chunk-S6CD7GFM.mjs → chunk-MQ57AB4U.mjs} +211 -35
- package/dist/sdk/chunk-MQ57AB4U.mjs.map +1 -0
- package/dist/sdk/chunk-N4I6ZDCJ.mjs +436 -0
- package/dist/sdk/chunk-N4I6ZDCJ.mjs.map +1 -0
- package/dist/sdk/chunk-OMFPM576.mjs +739 -0
- package/dist/sdk/chunk-OMFPM576.mjs.map +1 -0
- package/dist/sdk/chunk-RI77TA6V.mjs +436 -0
- package/dist/sdk/chunk-RI77TA6V.mjs.map +1 -0
- package/dist/sdk/chunk-VO4N6TEL.mjs +1502 -0
- package/dist/sdk/chunk-VO4N6TEL.mjs.map +1 -0
- package/dist/sdk/{chunk-V2IV3ILA.mjs → chunk-XJQKTK6V.mjs} +31 -5
- package/dist/sdk/chunk-XJQKTK6V.mjs.map +1 -0
- package/dist/sdk/{config-OGOS4ZU4.mjs → config-4EG7IQIU.mjs} +2 -2
- package/dist/sdk/{failure-condition-evaluator-HC3M5377.mjs → failure-condition-evaluator-GLHZZF47.mjs} +3 -3
- package/dist/sdk/failure-condition-evaluator-KN55WXRO.mjs +17 -0
- package/dist/sdk/{github-frontend-E2KJSC3Y.mjs → github-frontend-F4TE2JY7.mjs} +3 -3
- package/dist/sdk/github-frontend-HCOKL53D.mjs +1356 -0
- package/dist/sdk/github-frontend-HCOKL53D.mjs.map +1 -0
- package/dist/sdk/{host-EE6EJ2FM.mjs → host-SAT6RHDX.mjs} +2 -2
- package/dist/sdk/host-VA3ET7N6.mjs +63 -0
- package/dist/sdk/host-VA3ET7N6.mjs.map +1 -0
- package/dist/sdk/{liquid-extensions-E4EUOCES.mjs → liquid-extensions-YDIIH33Q.mjs} +2 -2
- package/dist/sdk/{routing-OZQWAGAI.mjs → routing-KFYQGOYU.mjs} +5 -5
- package/dist/sdk/routing-OXQKETSA.mjs +25 -0
- package/dist/sdk/{schedule-tool-handler-IEB2VS7O.mjs → schedule-tool-handler-G353DHS6.mjs} +7 -7
- package/dist/sdk/{schedule-tool-handler-B7TMSG6A.mjs → schedule-tool-handler-OQF57URO.mjs} +7 -7
- package/dist/sdk/schedule-tool-handler-PJVKWSYX.mjs +38 -0
- package/dist/sdk/schedule-tool-handler-PJVKWSYX.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +15 -0
- package/dist/sdk/sdk.d.ts +15 -0
- package/dist/sdk/sdk.js +621 -183
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +6 -6
- package/dist/sdk/{trace-helpers-PP3YHTAM.mjs → trace-helpers-LOPBHYYX.mjs} +4 -2
- package/dist/sdk/trace-helpers-LOPBHYYX.mjs.map +1 -0
- package/dist/sdk/trace-helpers-R2ETIEC2.mjs +25 -0
- package/dist/sdk/trace-helpers-R2ETIEC2.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-2ET3SFZH.mjs → workflow-check-provider-57KAR4Y4.mjs} +7 -7
- package/dist/sdk/workflow-check-provider-57KAR4Y4.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-HB4XTD4Z.mjs → workflow-check-provider-LRWD52WN.mjs} +7 -7
- package/dist/sdk/workflow-check-provider-LRWD52WN.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-N2DRFQDB.mjs +28 -0
- package/dist/sdk/workflow-check-provider-N2DRFQDB.mjs.map +1 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
- package/dist/state-machine/runner.d.ts.map +1 -1
- package/dist/state-machine/states/completed.d.ts.map +1 -1
- package/dist/telemetry/trace-helpers.d.ts +5 -0
- package/dist/telemetry/trace-helpers.d.ts.map +1 -1
- package/dist/test-runner/evaluators.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts +7 -0
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/traces/{run-2026-02-11T16-20-59-999Z.ndjson → run-2026-02-15T19-14-20-379Z.ndjson} +84 -84
- package/dist/{output/traces/run-2026-02-11T16-21-47-711Z.ndjson → traces/run-2026-02-15T19-15-09-410Z.ndjson} +1019 -1019
- package/dist/tui/chat-runner.d.ts.map +1 -1
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +2 -0
- package/dist/types/engine.d.ts.map +1 -1
- package/package.json +3 -3
- package/defaults/.visor.yaml +0 -420
- package/dist/sdk/chunk-EUUAQBTW.mjs.map +0 -1
- package/dist/sdk/chunk-S6CD7GFM.mjs.map +0 -1
- package/dist/sdk/chunk-UCNT3PDT.mjs.map +0 -1
- package/dist/sdk/chunk-V2IV3ILA.mjs.map +0 -1
- package/dist/sdk/chunk-YJRBN3XS.mjs +0 -217
- package/dist/sdk/chunk-YJRBN3XS.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-M3Y6JMTW.mjs.map → check-provider-registry-AAPPJ4CP.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-PANIXYRB.mjs.map → check-provider-registry-S7BMQ2FC.mjs.map} +0 -0
- /package/dist/sdk/{config-OGOS4ZU4.mjs.map → check-provider-registry-ZOLEYDKM.mjs.map} +0 -0
- /package/dist/sdk/{chunk-VMLORODQ.mjs.map → chunk-2GCSK3PD.mjs.map} +0 -0
- /package/dist/sdk/{chunk-HOKQOO3G.mjs.map → chunk-EBTD2D4L.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-HC3M5377.mjs.map → config-4EG7IQIU.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-E4EUOCES.mjs.map → failure-condition-evaluator-GLHZZF47.mjs.map} +0 -0
- /package/dist/sdk/{routing-OZQWAGAI.mjs.map → failure-condition-evaluator-KN55WXRO.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-E2KJSC3Y.mjs.map → github-frontend-F4TE2JY7.mjs.map} +0 -0
- /package/dist/sdk/{host-EE6EJ2FM.mjs.map → host-SAT6RHDX.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-B7TMSG6A.mjs.map → liquid-extensions-YDIIH33Q.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-IEB2VS7O.mjs.map → routing-KFYQGOYU.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-PP3YHTAM.mjs.map → routing-OXQKETSA.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-2ET3SFZH.mjs.map → schedule-tool-handler-G353DHS6.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-HB4XTD4Z.mjs.map → schedule-tool-handler-OQF57URO.mjs.map} +0 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
# Enterprise Licensing
|
|
2
|
+
|
|
3
|
+
> **Enterprise Edition feature.** Contact **hello@probelabs.com** for licensing.
|
|
4
|
+
|
|
5
|
+
This guide covers obtaining, installing, managing, and troubleshooting Visor Enterprise Edition licenses.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Overview](#overview)
|
|
12
|
+
- [Licensed Features](#licensed-features)
|
|
13
|
+
- [Obtaining a License](#obtaining-a-license)
|
|
14
|
+
- [Installing the License](#installing-the-license)
|
|
15
|
+
- [License Lookup Order](#license-lookup-order)
|
|
16
|
+
- [License Format](#license-format)
|
|
17
|
+
- [Grace Period](#grace-period)
|
|
18
|
+
- [Verifying Your License](#verifying-your-license)
|
|
19
|
+
- [Renewal](#renewal)
|
|
20
|
+
- [Rotation and Revocation](#rotation-and-revocation)
|
|
21
|
+
- [CI/CD Integration](#cicd-integration)
|
|
22
|
+
- [Air-Gapped Environments](#air-gapped-environments)
|
|
23
|
+
- [FAQ](#faq)
|
|
24
|
+
- [Troubleshooting](#troubleshooting)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Overview
|
|
29
|
+
|
|
30
|
+
Visor Enterprise Edition (EE) is a superset of the open-source version. All OSS functionality works identically without a license. Enterprise features are inert and silently disabled unless a valid license is present.
|
|
31
|
+
|
|
32
|
+
When a license is loaded:
|
|
33
|
+
1. Visor validates the cryptographic signature (EdDSA / Ed25519).
|
|
34
|
+
2. Checks the expiration date (with a 72-hour grace period).
|
|
35
|
+
3. Reads the `features` claim to determine which EE capabilities are active.
|
|
36
|
+
4. Caches the result for 5 minutes to avoid repeated validation.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Licensed Features
|
|
41
|
+
|
|
42
|
+
| Feature String | Capability | Documentation |
|
|
43
|
+
|---------------|------------|---------------|
|
|
44
|
+
| `policy` | OPA policy engine (check gating, tool access, capability control) | [Enterprise Policy Engine](./enterprise-policy.md) |
|
|
45
|
+
| `scheduler-sql` | PostgreSQL, MySQL, and MSSQL scheduler backends | [Scheduler Storage](./scheduler-storage.md) |
|
|
46
|
+
|
|
47
|
+
Features not listed in the license JWT are disabled. The OSS SQLite scheduler and all other OSS features work without a license.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Obtaining a License
|
|
52
|
+
|
|
53
|
+
### Trial License
|
|
54
|
+
|
|
55
|
+
Contact **hello@probelabs.com** with:
|
|
56
|
+
- Your organization name
|
|
57
|
+
- Expected number of Visor instances
|
|
58
|
+
- Which features you want to evaluate (`policy`, `scheduler-sql`, or both)
|
|
59
|
+
|
|
60
|
+
Trial licenses are typically issued for 30 days with all features enabled.
|
|
61
|
+
|
|
62
|
+
### Production License
|
|
63
|
+
|
|
64
|
+
Production licenses are issued per-organization and include:
|
|
65
|
+
- Organization name (`org` claim)
|
|
66
|
+
- Licensed features list
|
|
67
|
+
- Expiration date
|
|
68
|
+
- Unique subject identifier
|
|
69
|
+
|
|
70
|
+
Contact **hello@probelabs.com** or your account representative for production licensing.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Installing the License
|
|
75
|
+
|
|
76
|
+
### Option 1: Environment Variable (recommended for CI/CD and containers)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
export VISOR_LICENSE="eyJhbGciOiJFZERTQSIs..."
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The value is the raw JWT string (no file path, no prefix).
|
|
83
|
+
|
|
84
|
+
### Option 2: Environment Variable Pointing to File
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
export VISOR_LICENSE_FILE="/etc/visor/license.jwt"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The file should contain only the raw JWT string.
|
|
91
|
+
|
|
92
|
+
### Option 3: Project-Level File
|
|
93
|
+
|
|
94
|
+
Place a file named `.visor-license` in your project root (alongside `.visor.yaml`):
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
echo "eyJhbGciOiJFZERTQSIs..." > .visor-license
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Option 4: User-Level File
|
|
101
|
+
|
|
102
|
+
Place the license in your home config directory:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
mkdir -p ~/.config/visor
|
|
106
|
+
echo "eyJhbGciOiJFZERTQSIs..." > ~/.config/visor/.visor-license
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## License Lookup Order
|
|
112
|
+
|
|
113
|
+
Visor checks for a license in this order, using the first one found:
|
|
114
|
+
|
|
115
|
+
1. `VISOR_LICENSE` environment variable (raw JWT)
|
|
116
|
+
2. `VISOR_LICENSE_FILE` environment variable (file path)
|
|
117
|
+
3. `.visor-license` in the current working directory
|
|
118
|
+
4. `~/.config/visor/.visor-license` in the user's home directory
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## License Format
|
|
123
|
+
|
|
124
|
+
Licenses are Ed25519-signed JWTs (EdDSA algorithm) with the following payload:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"org": "Acme Corp",
|
|
129
|
+
"features": ["policy", "scheduler-sql"],
|
|
130
|
+
"exp": 1740000000,
|
|
131
|
+
"iat": 1708464000,
|
|
132
|
+
"sub": "org-acme-prod"
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
| Claim | Type | Description |
|
|
137
|
+
|-------|------|-------------|
|
|
138
|
+
| `org` | string | Organization name |
|
|
139
|
+
| `features` | string[] | Licensed feature strings |
|
|
140
|
+
| `exp` | number | Expiration timestamp (Unix seconds) |
|
|
141
|
+
| `iat` | number | Issue timestamp (Unix seconds) |
|
|
142
|
+
| `sub` | string | Subject identifier (unique per license) |
|
|
143
|
+
|
|
144
|
+
The signature is verified against Visor's embedded public key. Licenses cannot be forged or modified.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Grace Period
|
|
149
|
+
|
|
150
|
+
When a license expires, Visor provides a **72-hour grace period**:
|
|
151
|
+
|
|
152
|
+
| State | Behavior |
|
|
153
|
+
|-------|----------|
|
|
154
|
+
| **Valid** | All licensed features work normally |
|
|
155
|
+
| **Expired < 72 hours** | Features continue working; warning logged at startup |
|
|
156
|
+
| **Expired > 72 hours** | Enterprise features silently disable; OSS features unaffected |
|
|
157
|
+
|
|
158
|
+
During the grace period, Visor logs:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
[warn] Visor EE license expired. Grace period active (expires in Xh). Please renew.
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Verifying Your License
|
|
167
|
+
|
|
168
|
+
### Check at Startup
|
|
169
|
+
|
|
170
|
+
Run Visor with `--debug` to see license validation output:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
visor --debug --config .visor.yaml --check all 2>&1 | grep -i license
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
With a valid license:
|
|
177
|
+
```
|
|
178
|
+
[debug] [License] Valid license for "Acme Corp" (features: policy, scheduler-sql, expires: 2026-06-01)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Without a license:
|
|
182
|
+
```
|
|
183
|
+
[debug] [License] No license found. Enterprise features disabled.
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Check Feature Availability
|
|
187
|
+
|
|
188
|
+
If a feature is used without a license, Visor logs a debug message and falls back to OSS behavior:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
[debug] [Policy] Policy engine disabled (no license or feature not licensed)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Renewal
|
|
197
|
+
|
|
198
|
+
### Before Expiration
|
|
199
|
+
|
|
200
|
+
1. Contact **hello@probelabs.com** or your account representative.
|
|
201
|
+
2. Provide your current `sub` claim (from your existing license) for continuity.
|
|
202
|
+
3. Receive a new JWT with an updated `exp` claim.
|
|
203
|
+
4. Replace the old license using any of the [installation methods](#installing-the-license).
|
|
204
|
+
5. Visor picks up the new license within 5 minutes (cache TTL) or on next restart.
|
|
205
|
+
|
|
206
|
+
### After Expiration (within grace period)
|
|
207
|
+
|
|
208
|
+
Same process as above. Enterprise features continue working during the 72-hour grace period.
|
|
209
|
+
|
|
210
|
+
### After Grace Period
|
|
211
|
+
|
|
212
|
+
Enterprise features are disabled but **no data is lost**. Once a new license is installed:
|
|
213
|
+
- Policy engine re-enables immediately.
|
|
214
|
+
- SQL scheduler backends reconnect automatically.
|
|
215
|
+
- All previously stored schedules and policies remain intact.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Rotation and Revocation
|
|
220
|
+
|
|
221
|
+
### Rotating a License
|
|
222
|
+
|
|
223
|
+
To rotate to a new license (e.g., changing features or extending expiration):
|
|
224
|
+
|
|
225
|
+
1. Obtain the new license JWT.
|
|
226
|
+
2. Replace the old license (env var, file, or config file).
|
|
227
|
+
3. Restart Visor or wait up to 5 minutes for cache refresh.
|
|
228
|
+
|
|
229
|
+
Both old and new licenses can coexist briefly during rotation. Visor uses whichever it finds first in the lookup order.
|
|
230
|
+
|
|
231
|
+
### Revoking a License
|
|
232
|
+
|
|
233
|
+
To immediately revoke enterprise features:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Remove from environment
|
|
237
|
+
unset VISOR_LICENSE
|
|
238
|
+
unset VISOR_LICENSE_FILE
|
|
239
|
+
|
|
240
|
+
# Remove from filesystem
|
|
241
|
+
rm .visor-license
|
|
242
|
+
rm ~/.config/visor/.visor-license
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Restart Visor. Enterprise features will be silently disabled.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## CI/CD Integration
|
|
250
|
+
|
|
251
|
+
### GitHub Actions
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
- name: Run Visor
|
|
255
|
+
env:
|
|
256
|
+
VISOR_LICENSE: ${{ secrets.VISOR_LICENSE }}
|
|
257
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
258
|
+
run: visor --config .visor.yaml --check all
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### GitLab CI
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
visor:
|
|
265
|
+
image: node:20
|
|
266
|
+
variables:
|
|
267
|
+
VISOR_LICENSE: $VISOR_LICENSE
|
|
268
|
+
script:
|
|
269
|
+
- npm install -g @probelabs/visor@ee
|
|
270
|
+
- visor --config .visor.yaml --check all
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Jenkins
|
|
274
|
+
|
|
275
|
+
```groovy
|
|
276
|
+
pipeline {
|
|
277
|
+
environment {
|
|
278
|
+
VISOR_LICENSE = credentials('visor-license')
|
|
279
|
+
}
|
|
280
|
+
stages {
|
|
281
|
+
stage('Review') {
|
|
282
|
+
steps {
|
|
283
|
+
sh 'visor --config .visor.yaml --check all'
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Kubernetes Secret
|
|
291
|
+
|
|
292
|
+
```yaml
|
|
293
|
+
apiVersion: v1
|
|
294
|
+
kind: Secret
|
|
295
|
+
metadata:
|
|
296
|
+
name: visor-license
|
|
297
|
+
type: Opaque
|
|
298
|
+
stringData:
|
|
299
|
+
VISOR_LICENSE: "eyJhbGciOiJFZERTQSIs..."
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Reference in deployment:
|
|
303
|
+
|
|
304
|
+
```yaml
|
|
305
|
+
envFrom:
|
|
306
|
+
- secretRef:
|
|
307
|
+
name: visor-license
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Air-Gapped Environments
|
|
313
|
+
|
|
314
|
+
Visor licenses are validated entirely offline. No network calls are made during license validation. This makes Visor EE fully compatible with air-gapped and restricted network environments.
|
|
315
|
+
|
|
316
|
+
Requirements:
|
|
317
|
+
- The license JWT must be available via one of the [lookup methods](#license-lookup-order).
|
|
318
|
+
- The EE npm package (`@probelabs/visor@ee`) must be installed from a local registry or tarball.
|
|
319
|
+
- For OPA policies, pre-compile `.rego` to `.wasm` externally and reference the `.wasm` file directly.
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## FAQ
|
|
324
|
+
|
|
325
|
+
**Q: What happens if I remove the license?**
|
|
326
|
+
A: Enterprise features silently disable. OSS features continue working. No data is lost. Schedules stored in PostgreSQL remain accessible once a license is restored.
|
|
327
|
+
|
|
328
|
+
**Q: Can I use the same license on multiple machines?**
|
|
329
|
+
A: Yes. Licenses are not node-locked. They are valid for the licensed organization across any number of instances.
|
|
330
|
+
|
|
331
|
+
**Q: Does Visor phone home?**
|
|
332
|
+
A: No. License validation is entirely offline using cryptographic signature verification. No telemetry or usage data is sent to Probelabs for licensing purposes.
|
|
333
|
+
|
|
334
|
+
**Q: What happens during a deploy if the license secret isn't set?**
|
|
335
|
+
A: Visor starts normally with OSS-only features. Enterprise features are disabled until the license is available.
|
|
336
|
+
|
|
337
|
+
**Q: Can I downgrade from EE to OSS?**
|
|
338
|
+
A: Yes. Replace `@probelabs/visor@ee` with `@probelabs/visor`. Remove the license. If you were using PostgreSQL, switch the scheduler config back to `driver: sqlite` and Visor will use the local SQLite database.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## Troubleshooting
|
|
343
|
+
|
|
344
|
+
### "No license found"
|
|
345
|
+
|
|
346
|
+
- Check the [lookup order](#license-lookup-order) and verify the license is accessible.
|
|
347
|
+
- For containers: ensure the env var or file mount is correctly configured.
|
|
348
|
+
- Run `visor --debug` to see which paths Visor checks.
|
|
349
|
+
|
|
350
|
+
### "License signature invalid"
|
|
351
|
+
|
|
352
|
+
- Ensure the JWT is not truncated or modified.
|
|
353
|
+
- Verify you're using a license issued by Probelabs (not a self-signed token).
|
|
354
|
+
- Check for trailing whitespace or newlines in the license string.
|
|
355
|
+
|
|
356
|
+
### "License expired"
|
|
357
|
+
|
|
358
|
+
- Check the `exp` claim: `echo "YOUR_JWT" | cut -d. -f2 | base64 -d 2>/dev/null | jq .exp`
|
|
359
|
+
- Contact **hello@probelabs.com** for renewal.
|
|
360
|
+
- The 72-hour grace period provides time to obtain a new license.
|
|
361
|
+
|
|
362
|
+
### "Feature not licensed"
|
|
363
|
+
|
|
364
|
+
- Check your license's `features` claim matches the feature you're using.
|
|
365
|
+
- `policy` is required for OPA policy engine.
|
|
366
|
+
- `scheduler-sql` is required for PostgreSQL/MySQL/MSSQL backends.
|
|
367
|
+
|
|
368
|
+
### License Not Picked Up After Update
|
|
369
|
+
|
|
370
|
+
- Visor caches license validation for 5 minutes. Wait or restart.
|
|
371
|
+
- If using `VISOR_LICENSE_FILE`, verify the file path hasn't changed.
|
|
372
|
+
- Check file permissions (must be readable by the Visor process).
|