@microsoft/rayfin-guide 1.36.0-alpha.1593 → 1.36.0-alpha.1601

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.
@@ -0,0 +1,38 @@
1
+ ---
2
+ sidebar_position: 3
3
+ ---
4
+
5
+ # up functions deploy
6
+
7
+ Build, package, and deploy your functions to the remote Rayfin item.
8
+
9
+ ```bash
10
+ npx rayfin up functions deploy [-v | --verbose] [--skip-build] [--json]
11
+ ```
12
+
13
+ ## When to use it
14
+
15
+ `npx rayfin up` already deploys functions as part of a full deployment. Use `up functions deploy` when you want to run **only** the functions step — for example to retry after a functions deploy failed, or to push a functions-only change without redeploying the rest of the app.
16
+
17
+ ## Prerequisites
18
+
19
+ Run `npx rayfin up` at least once first. This command deploys to an existing remote item, so a remote endpoint must already exist. If there is no active deployment, run a full `npx rayfin up`.
20
+
21
+ ## Options
22
+
23
+ | Option | Description |
24
+ | --------------- | -------------------------------------------------------------- |
25
+ | `-v, --verbose` | Print detailed build and deploy output. |
26
+ | `--skip-build` | Deploy the already-built output without rebuilding first. |
27
+ | `--json` | Emit machine-readable JSON instead of human-readable progress. |
28
+
29
+ ## What it does
30
+
31
+ 1. Builds and packages the functions project (unless `--skip-build`).
32
+ 2. Deploys the package to the remote Rayfin item resolved from your active deployment.
33
+
34
+ ## Related
35
+
36
+ - [`functions init`](./init.md) — scaffold and enable functions.
37
+ - [`dev functions apply`](./dev-apply.md) — run and debug functions locally before deploying.
38
+ - [Managing Secrets](../secrets.md) — push secrets that deployed functions read via `ctx.getSecret`.
@@ -0,0 +1,62 @@
1
+ ---
2
+ sidebar_position: 2
3
+ ---
4
+
5
+ # dev functions apply
6
+
7
+ Start the local Rayfin functions runtime against your active deployment, with a live typegen watcher and debugger support. This is the command you run while developing and debugging functions.
8
+
9
+ ```bash
10
+ npx rayfin dev functions apply [--port <port>] [--inspect-port <port>] [--no-debug] [--no-emit-env]
11
+ ```
12
+
13
+ ## Prerequisites
14
+
15
+ - **Functions must be enabled** — run [`npx rayfin functions init`](./init.md) first so `services.functions.enabled` is set in `rayfin.yml`.
16
+ - **Node.js ≥ 20** and **Azure Functions Core Tools** must be installed. The command verifies these and, with your consent, installs Core Tools if missing.
17
+ - **An active deployment** — run `npx rayfin up` at least once so a remote endpoint and publishable key exist to resolve against.
18
+
19
+ ## Options
20
+
21
+ | Option | Default | Description |
22
+ | ----------------------- | ------- | ----------------------------------------------------------------------------- |
23
+ | `--port <port>` | `7071` | Port for the local function host. Auto-shifts to the next free port if taken. |
24
+ | `--inspect-port <port>` | `9229` | Port for the Node inspector (debugger). |
25
+ | `--no-debug` | off | Disable the inspector / attach support. |
26
+ | `--no-emit-env` | off | Skip regenerating the framework `.env.local`. |
27
+
28
+ ## What it does
29
+
30
+ 1. Gates on `services.functions.enabled` and checks prerequisites (Node, Core Tools).
31
+ 2. Resolves the active deployment and publishable key.
32
+ 3. Writes `rayfin/functions/local.settings.json` (environment, API URL, publishable key, workspace/item ids, inspector flag when debugging).
33
+ 4. Upserts `RAYFIN_PUBLIC_FUNCTIONS_URL` into `rayfin/.env` and regenerates the framework `.env.local` (unless `--no-emit-env`).
34
+ 5. Preserves the existing same-origin adapter in bundled Vite templates.
35
+ For recognized older or custom Vite clients, the first run patches `functionsBaseUrl` to read the generated URL only during development.
36
+ 6. Builds the functions project, runs a one-shot typegen, then starts a visible **typegen watcher** (`[typegen]` prefix) that keeps `src/types.ts` in sync as you edit `function_app.ts`.
37
+ 7. Starts `func start` in the foreground and writes a `.vscode/launch.json` **"Functions: Attach"** configuration for debugging.
38
+
39
+ Press `Ctrl+C` to stop the host and watcher.
40
+ This command does not start the frontend.
41
+ Run the Vite frontend separately to invoke local functions through `/.rayfin/api/<name>`, or use `npx rayfin dev` to start both together.
42
+ If the local Functions host is unavailable, the Vite adapter returns HTTP 502 instead of invoking deployed function code.
43
+
44
+ ## Debugging
45
+
46
+ With debugging enabled (default), attach your debugger to the inspector port (`9229` by default) using the generated **"Functions: Attach"** launch configuration in VS Code. Pass `--no-debug` to run without the inspector.
47
+
48
+ ## Secrets in local development
49
+
50
+ Locally there is no deployed secret bag, so `ctx.getSecret(name)` falls back to `process.env`. To provide a secret, add it under `Values` in `rayfin/functions/local.settings.json`; the functions host loads those entries into `process.env`. See [Managing Secrets](../secrets.md#using-secrets-in-local-development).
51
+
52
+ ## Next step
53
+
54
+ When your functions are working locally, deploy them:
55
+
56
+ ```bash
57
+ npx rayfin up # deploys everything, including functions
58
+ # or, to re-run only functions:
59
+ npx rayfin up functions deploy
60
+ ```
61
+
62
+ See [`up functions deploy`](./deploy.md).
@@ -0,0 +1,41 @@
1
+ ---
2
+ sidebar_position: 4
3
+ ---
4
+
5
+ # Functions
6
+
7
+ Rayfin functions are server-side user-defined functions (UDFs) that run in the Fabric runtime and are invocable from your frontend through `RayfinClient`. Use them for logic that must run on the backend — secrets and API keys, privileged data access, server-side validation, and anything that should not be exposed or tampered with in client code.
8
+
9
+ The functions project lives at `rayfin/functions/` and is enabled by the `services.functions.enabled` flag in `rayfin.yml` (set for you the first time you run [`functions init`](./init.md)).
10
+
11
+ Each command has its own reference page:
12
+
13
+ - [`functions init`](./init.md) — scaffold `rayfin/functions/`, install dependencies, and seed `types.ts`.
14
+ - [`dev functions apply`](./dev-apply.md) — run the local function host with a live typegen watcher for development and debugging.
15
+ - [`up functions deploy`](./deploy.md) — build, package, and deploy functions to the remote Rayfin item.
16
+
17
+ ## The development loop
18
+
19
+ ```text
20
+ functions init → write UDFs in src/function_app.ts → dev functions apply → up
21
+ (scaffold) (typegen keeps types.ts fresh) (local host+debug) (deploy)
22
+ ```
23
+
24
+ 1. **`npx rayfin functions init`** scaffolds the project, installs dependencies, runs a one-shot typegen, and enables the service in `rayfin.yml`.
25
+ 2. **Write functions** with `udf.func(name, handler, [])` in `rayfin/functions/src/function_app.ts`. The CLI parses these calls and generates `rayfin/functions/src/types.ts` (the `AppFunctionsSchema`) — never hand-edit it.
26
+ 3. **`npx rayfin dev functions apply`** starts the local Azure Functions host, keeps a visible `[typegen]` watcher running so `types.ts` stays in sync as you edit, and publishes its URL for local frontend routing.
27
+ Bundled Vite apps use that URL through the same-origin `/.rayfin/api/<name>` route when you run the frontend separately.
28
+ 4. **`npx rayfin up`** deploys everything, including functions. To re-run only the functions step, use [`npx rayfin up functions deploy`](./deploy.md).
29
+
30
+ > **`npx rayfin dev` vs. `npx rayfin dev functions apply`:** Prefer `npx rayfin dev` for normal local development because it runs your functions alongside the frontend and backend. Use `npx rayfin dev functions apply` when you want to run **only** the functions host — with its typegen watcher and debugger — without starting the frontend/static app.
31
+
32
+ ## Where functions state lives
33
+
34
+ - `rayfin/functions/src/function_app.ts` — where you register UDFs with `udf.func()`.
35
+ - `rayfin/functions/src/types.ts` — auto-generated `AppFunctionsSchema`; regenerated by `functions init` (one-shot) and by the watcher inside `dev functions apply`.
36
+ - `rayfin/functions/{package.json,host.json,tsconfig.json,local.settings.json}` — the functions app manifest, host config, TypeScript project references, and local settings.
37
+ - `rayfin.yml` — the `services.functions` block (`enabled`, `buildCommand`).
38
+
39
+ ## Secrets
40
+
41
+ Functions read secrets at runtime with `ctx.getSecret(name)`, backed by the host secret bag with a `process.env` fallback. Manage remote secrets with `npx rayfin secret set` — or bulk-set them from a file with `npx rayfin secret set --env-file` — see [Managing Secrets](../secrets.md).
@@ -0,0 +1,62 @@
1
+ ---
2
+ sidebar_position: 1
3
+ ---
4
+
5
+ # functions init
6
+
7
+ Scaffold a Rayfin functions project under `rayfin/functions/`, enable the functions service, install dependencies, build, and generate the initial types.
8
+
9
+ ```bash
10
+ npx rayfin functions init [directory] [--force]
11
+ ```
12
+
13
+ ## Prerequisites
14
+
15
+ Run this from a directory that already contains a `rayfin/` project (i.e. you have already run `npx rayfin init`). If `rayfin/` is missing, the command errors and asks you to initialize the app first.
16
+
17
+ ## Arguments and options
18
+
19
+ | Name | Description |
20
+ | ------------- | ---------------------------------------------------------------------------------------------------- |
21
+ | `[directory]` | Project directory to initialize in. Defaults to the current directory (`.`). |
22
+ | `--force` | Overwrite an existing `rayfin/functions/` scaffold. Without it, existing function code is preserved. |
23
+
24
+ ## What it does
25
+
26
+ 1. **Scaffolds** `rayfin/functions/` with a starter function app, `host.json`, `tsconfig.json`, `package.json`, and `local.settings.json`.
27
+ 2. **Enables the service** in `rayfin.yml` by setting `services.functions.enabled: true` and `services.functions.buildCommand: 'npm run build'`.
28
+ 3. **Installs dependencies** for the functions project.
29
+ 4. **Builds** the project.
30
+ 5. **Generates types** — runs a one-shot typegen to produce `rayfin/functions/src/types.ts` (the `AppFunctionsSchema`).
31
+ 6. **Installs AI agent files** so assistants understand the functions surface.
32
+
33
+ ## Scaffolded structure
34
+
35
+ ```text
36
+ rayfin/
37
+ functions/
38
+ src/
39
+ function_app.ts # register UDFs here with udf.func(...)
40
+ types.ts # generated AppFunctionsSchema — do not hand-edit
41
+ host.json
42
+ local.settings.json
43
+ package.json
44
+ tsconfig.json
45
+ ```
46
+
47
+ ## Re-running
48
+
49
+ `functions init` is safe to re-run:
50
+
51
+ - **Without `--force`** on an existing project, it preserves your `function_app.ts` and only refreshes dependencies, build, and generated types.
52
+ - **With `--force`**, it overwrites the scaffold (a warning is shown before your files are replaced).
53
+
54
+ ## Next step
55
+
56
+ Start the local host and typegen watcher:
57
+
58
+ ```bash
59
+ npx rayfin dev functions apply
60
+ ```
61
+
62
+ See [`dev functions apply`](./dev-apply.md).
@@ -61,9 +61,29 @@ For the full walkthrough, see the [CLI Quickstart](./quickstart.md) or the [Buil
61
61
  | `npx rayfin up` | Deploy the project to Microsoft Fabric. If you are not signed in, the CLI launches an interactive login flow. Use `-t, --tenant <id>` when your account spans multiple tenants, `-w, --workspace <name>` for a Fabric workspace display name, `-n, --dry-run` to preview without API calls, and `-v, --verbose` for detailed output. Pass `--encryption-fallback-enabled` only when login fails with a keychain error to allow plaintext token storage on systems without OS credential storage, such as some Linux distros, dev containers, and Codespaces. Use `--exclude-services staticHosting` to skip static content build/package/deploy while leaving runtime settings untouched — useful during local development when Vite serves the frontend. Applies runtime settings, database configuration, and static content when enabled. |
62
62
  | `npx rayfin up status` | Display the status of the Fabric deployment (add `--json` for machine-readable output). |
63
63
  | `npx rayfin up db apply` | Generate and apply DAB configuration to the remote Rayfin item. Add `--force` to allow changes that may cause data loss. |
64
- | `npx rayfin up secrets apply` | Read secrets from `rayfin/.env` file (prefixed with `RAYFIN_SECRET_`) and securely apply them to the remote Rayfin item workload. Validates that secrets are persisted. Use `--env-file <path>` to specify a custom .env file location. |
65
64
  | `npx rayfin up staticapp deploy` | Build, package, and deploy static content to the remote Rayfin item. Add `--skip-build` to deploy existing build output without rebuilding. |
66
65
 
66
+ ### Functions
67
+
68
+ Functions are server-side user-defined functions (UDFs) that run in the Fabric runtime and are invocable from your frontend through `RayfinClient`. Use them for logic that must run on the backend — secrets, privileged data access, and server-side validation. See [Functions](./functions/index.md) for the full guide.
69
+
70
+ | Command | Description |
71
+ | --- | --- |
72
+ | `npx rayfin functions init [directory]` | Scaffold `rayfin/functions/`, enable the functions service, install dependencies, build, and generate types. See [functions init](./functions/init.md). |
73
+ | `npx rayfin dev functions apply` | Run the local function host with a live typegen watcher and debugger support. See [dev functions apply](./functions/dev-apply.md). |
74
+ | `npx rayfin up functions deploy` | Build, package, and deploy functions to the remote Rayfin item. `rayfin up` runs this automatically. See [up functions deploy](./functions/deploy.md). |
75
+
76
+ ### Secrets
77
+
78
+ Secrets are encrypted values stored on your deployed Rayfin item and read at runtime — for example by [functions](./functions/index.md) via `ctx.getSecret`. See [Managing Secrets](./secrets.md) for the full guide.
79
+
80
+ | Command | Description |
81
+ | --- | --- |
82
+ | `npx rayfin secret set <name>` | Set a single secret on the deployed item with a masked prompt. Use `--stdin` for non-interactive input and `--describe="..."` to record a description in `rayfin.yml`. |
83
+ | `npx rayfin secret set --env-file <path>` | Bulk-set every `KEY=VALUE` entry from a dotenv file. |
84
+ | `npx rayfin secret list` | List secret names and their created/updated timestamps (values are never returned). |
85
+ | `npx rayfin secret delete <name>` | Delete a secret from the deployed item. Add `-y, --yes` to skip the confirmation prompt. |
86
+
67
87
  ## Update the CLI
68
88
 
69
89
  To get the latest version of the Rayfin CLI and its dependencies:
@@ -4,193 +4,168 @@ sidebar_position: 50
4
4
 
5
5
  # Managing Secrets
6
6
 
7
- The Rayfin CLI provides secure secret management for your remote deployments.
8
- Secrets are encrypted and stored securely in your Rayfin item workload.
7
+ Secrets are encrypted values API keys, connection strings, tokens — that your app needs at runtime but must never ship in client code. They are stored securely on your deployed Rayfin item and read on the server by [functions](./functions/index.md) via `ctx.getSecret(name)`.
9
8
 
10
- ## Overview
9
+ Manage secrets with the `npx rayfin secret` command group:
11
10
 
12
- Use the `rayfin up secrets apply` command to manage application secrets for your remote deployment.
13
- Secrets are read from your `.env` file, securely transmitted to your workload, encrypted, and validated.
11
+ | Command | Description |
12
+ | ----------------------------------------- | ---------------------------------------------------- |
13
+ | `npx rayfin secret set <name>` | Set one secret (masked prompt or `--stdin`). |
14
+ | `npx rayfin secret set --env-file <path>` | Bulk-set every `KEY=VALUE` entry from a dotenv file. |
15
+ | `npx rayfin secret list` | List secret names and timestamps (never values). |
16
+ | `npx rayfin secret delete <name>` | Delete a secret. |
14
17
 
15
- ## Setting up secrets
18
+ ## Prerequisite: deploy first
16
19
 
17
- ### 1. Define secrets in `.env`
18
-
19
- Create a `rayfin/.env` file with secrets prefixed using `RAYFIN_SECRET_`:
20
+ Secrets live on the remote Rayfin item, so you must deploy before managing them:
20
21
 
21
22
  ```bash
22
- # rayfin/.env
23
- RAYFIN_SECRET_API_KEY=sk-prod-abc123xyz789
24
- RAYFIN_SECRET_DATABASE_PASSWORD=secure-db-pass-123
25
- RAYFIN_SECRET_AUTH_TOKEN=token-abcdefg-hijklmn
26
- RAYFIN_SECRET_OPENAI_KEY=sk-openai-your-key-here
23
+ npx rayfin up
27
24
  ```
28
25
 
29
- > **Secret naming:** Secret names must follow the `RAYFIN_SECRET_` prefix convention.
30
- > The part after the prefix becomes your secret name.
31
- > For example, `RAYFIN_SECRET_API_KEY` creates a secret named `API_KEY`.
26
+ Every `secret` command resolves the remote endpoint from your active deployment. If none exists, the CLI stops with:
27
+
28
+ ```text
29
+ ❌ No remote endpoint configured
30
+ Run 'npx rayfin up' first to deploy your item to Fabric.
31
+ ```
32
32
 
33
- ### 2. Deploy your item
33
+ ## Setting a secret
34
34
 
35
- Before managing secrets, deploy your project to Microsoft Fabric:
35
+ By default, `secret set` prompts for the value with masked input:
36
36
 
37
37
  ```bash
38
- npx rayfin up
38
+ npx rayfin secret set OPENAI_KEY
39
+ # ? Enter secret value for "OPENAI_KEY" ********
39
40
  ```
40
41
 
41
- This creates your Rayfin item and sets up the workload endpoint.
42
-
43
- ### 3. Apply secrets
44
-
45
- Apply your secrets to the remote workload:
42
+ For non-interactive use (CI, scripts), pipe the value in with `--stdin`:
46
43
 
47
44
  ```bash
48
- npx rayfin up secrets apply
45
+ echo "sk-openai-your-key-here" | npx rayfin secret set OPENAI_KEY --stdin
49
46
  ```
50
47
 
51
- The CLI will:
52
- 1. Read your `rayfin/.env` file
53
- 2. Extract all `RAYFIN_SECRET_*` variables
54
- 3. Securely send each secret to your workload
55
- 4. Encrypt and persist the secrets
56
- 5. Validate that all secrets were successfully saved
57
-
58
- ### 4. Verify secrets
48
+ ### Recording a description in `rayfin.yml`
59
49
 
60
- After running the apply command, you'll see output confirming each secret:
50
+ Use `--describe` to record a human-readable description alongside the secret's metadata in `rayfin/rayfin.yml` (the value itself is never written to `rayfin.yml`). The flag **must** use the `=` syntax:
61
51
 
62
- ```text
63
- 🔐 Acquiring authentication token...
64
- ✓ Token acquired
65
- 📤 Sending 4 secret(s) to workload...
66
- ✓ Secrets sent to workload (4 persisted)
67
- ✅ Validating secrets persisted to workload...
68
- ✓ All secrets validated
69
-
70
- ✨ Secrets applied successfully (4/4)
71
- ✓ API_KEY
72
- ✓ DATABASE_PASSWORD
73
- ✓ AUTH_TOKEN
74
- ✓ OPENAI_KEY
52
+ ```bash
53
+ npx rayfin secret set OPENAI_KEY --describe="OpenAI API key for the chat function"
75
54
  ```
76
55
 
77
- ## Advanced usage
56
+ Passing `--describe "..."` with a space is rejected — always use `--describe="..."`.
78
57
 
79
- ### Custom .env file location
58
+ ## Bulk-setting from a file
80
59
 
81
- If your secrets are in a non-standard location, use the `--env-file` option:
60
+ To set many secrets at once, keep them in a dotenv file and point `secret set` at it with `--env-file`:
82
61
 
83
62
  ```bash
84
- npx rayfin up secrets apply --env-file ./config/secrets.env
63
+ # rayfin/.env.secrets
64
+ OPENAI_KEY=sk-openai-your-key-here
65
+ DATABASE_PASSWORD=secure-db-pass-123
66
+ AUTH_TOKEN=token-abcdefg-hijklmn
85
67
  ```
86
68
 
87
- ### JSON output
88
-
89
- For automation or scripting, use `--json` for machine-readable output:
90
-
91
69
  ```bash
92
- npx rayfin up secrets apply --json
70
+ npx rayfin secret set --env-file rayfin/.env.secrets
93
71
  ```
94
72
 
95
- Output example:
96
-
97
- ```json
98
- {
99
- "status": "success",
100
- "message": "All secrets applied and validated",
101
- "secretsCount": 4,
102
- "persisted": 4,
103
- "validated": true,
104
- "secrets": [
105
- {
106
- "name": "API_KEY",
107
- "id": "secret-123",
108
- "createdAt": "2026-04-17T10:30:00Z"
109
- }
110
- ]
111
- }
112
- ```
73
+ Every `KEY=VALUE` line becomes a secret named `KEY` — there is **no prefix convention**; the key is used verbatim. Blank lines and `#` comments are ignored, and surrounding single or double quotes are stripped from values. Do not pass a `<name>` together with `--env-file`, and do not combine `--env-file` with `--stdin`.
113
74
 
114
- ### Verbose logging
75
+ > **Keep secret files out of version control.** Add your secrets file to `.gitignore` — it is for authoring only, never committed:
76
+ >
77
+ > ```bash
78
+ > echo "rayfin/.env.secrets" >> .gitignore
79
+ > ```
115
80
 
116
- Enable detailed logging for debugging:
81
+ ## Listing secrets
117
82
 
118
83
  ```bash
119
- npx rayfin up secrets apply --verbose
84
+ npx rayfin secret list
120
85
  ```
121
86
 
122
- ### Non-interactive mode
87
+ Only names and created/updated timestamps are returned — values are never read back:
123
88
 
124
- Use `-y` or `--yes` to skip confirmation prompts:
89
+ ```text
90
+ 📋 Secrets (3):
125
91
 
126
- ```bash
127
- npx rayfin up secrets apply -y
92
+ Name: OPENAI_KEY
93
+ Created: 4/17/2026, 10:30:00 AM
94
+ Last Updated: 4/17/2026, 10:30:00 AM
128
95
  ```
129
96
 
130
- ## Secret handling and security
97
+ ## Deleting a secret
131
98
 
132
- ### Encryption
99
+ ```bash
100
+ npx rayfin secret delete OPENAI_KEY # prompts for confirmation
101
+ npx rayfin secret delete OPENAI_KEY --yes # skips the prompt (-y)
102
+ ```
133
103
 
134
- Secrets are transmitted over HTTPS with encrypted payloads.
135
- The workload endpoint encrypts and persists secrets securely.
136
- Secrets are never logged or displayed after being sent to the workload.
104
+ Deleting a secret that does not exist reports a not-found error — run `npx rayfin secret list` to see what is currently stored.
137
105
 
138
- ### Best practices
106
+ ## Reading secrets from functions
139
107
 
140
- 1. **Use `.env` files for local development only** Never commit `.env` files to version control.
141
- Add `.env` to your `.gitignore`:
108
+ Server-side functions read secrets at runtime with `ctx.getSecret(name)`, which resolves against the deployed item's secret bag and falls back to `process.env`. Set a secret with `npx rayfin secret set <name>`, then read it by the same name inside your handler:
142
109
 
143
- ```bash
144
- echo "rayfin/.env" >> .gitignore
145
- ```
110
+ ```ts
111
+ udf.func("summarize", async (ctx, input: { text: string }) => {
112
+ const apiKey = ctx.getSecret("OPENAI_KEY");
113
+ // ... call the API with apiKey
114
+ });
115
+ ```
146
116
 
147
- 2. **Use environment variables for CI/CD** – In automated environments, set `RAYFIN_SECRET_*` variables directly:
117
+ ## Using secrets in local development
148
118
 
149
- ```bash
150
- export RAYFIN_SECRET_API_KEY=prod-key-from-vault
151
- npx rayfin up secrets apply
152
- ```
119
+ When you run functions locally with [`npx rayfin dev functions apply`](./functions/dev-apply.md), there is no deployed secret bag, so `ctx.getSecret(name)` falls back to `process.env`. To make a secret available locally, add it under `Values` in `rayfin/functions/local.settings.json` — the Azure Functions host loads those entries into `process.env`:
153
120
 
154
- 3. **Rotate secrets regularly** – Re-run `rayfin up secrets apply` after updating secret values in your `.env` file.
121
+ ```json
122
+ {
123
+ "IsEncrypted": false,
124
+ "Values": {
125
+ "OPENAI_KEY": "sk-local-dev-key"
126
+ }
127
+ }
128
+ ```
155
129
 
156
- 4. **Separate development and production secrets** Use different `.env` files or environment variables for each environment.
130
+ `npx rayfin dev functions apply` **merges** its own CLI-managed values into `local.settings.json` and preserves any keys you add, so your local secrets survive re-runs. Keep `local.settings.json` out of version control — it is for local development only.
157
131
 
158
- ## Troubleshooting
132
+ ## Automation and JSON output
159
133
 
160
- ### No secrets found
134
+ Every `secret` command accepts the global `--json` flag for machine-readable output and `--verbose` for detailed logging:
135
+
136
+ ```bash
137
+ npx rayfin secret list --json
138
+ npx rayfin secret set OPENAI_KEY --stdin --json < key.txt
139
+ ```
161
140
 
162
- If you see "No secrets found in .env file", verify:
141
+ ## Security notes
163
142
 
164
- - Your `.env` file exists at `rayfin/.env`
165
- - Variables are prefixed with `RAYFIN_SECRET_`
166
- - The file is readable by the CLI process
143
+ - Secrets are transmitted over HTTPS and encrypted at rest on the workload. They are never logged or displayed after being sent.
144
+ - `npx rayfin secret list` returns only names and timestamps — never values.
145
+ - Use separate secret values per environment, and rotate them by re-running `npx rayfin secret set` with the new value.
167
146
 
168
- ### Authentication failed
147
+ ## Troubleshooting
169
148
 
170
- If you see "Failed to acquire authentication token":
149
+ ### No remote endpoint configured
171
150
 
172
- - Run `npx rayfin login` to sign in
173
- - Check that you have valid Entra ID credentials
174
- - On containers or restricted environments, use `--encryption-fallback-enabled` or set `RAYFIN_ENCRYPTION_FALLBACK_ENABLED=true`
151
+ Run `npx rayfin up` first to deploy your item, then retry. Secrets cannot be managed before an initial deployment exists.
175
152
 
176
- ### Validation inconclusive
153
+ ### Authentication failed
177
154
 
178
- If some secrets fail validation:
155
+ If acquiring a token fails:
179
156
 
180
- - Check your network connection to Fabric
181
- - Verify the workload endpoint is running and healthy
182
- - Run `npx rayfin up status` to confirm deployment health
183
- - Re-run `npx rayfin up secrets apply` to retry
157
+ - Run `npx rayfin login` to sign in and confirm you have valid Entra ID credentials.
158
+ - On containers or restricted environments without an OS keychain, pass `--encryption-fallback-enabled` to allow plaintext token storage.
184
159
 
185
- ### Permission denied
160
+ ### Secret not found on delete
186
161
 
187
- If you see permission errors:
162
+ If `secret delete` reports the secret was not found:
188
163
 
189
- - Ensure you're authenticated with an account that has access to the Fabric workspace
190
- - Verify you have the correct workspace selected
191
- - Run `npx rayfin login --select` to choose a different account/tenant
164
+ - It may already be deleted run `npx rayfin secret list` to confirm.
165
+ - Secret management may not be enabled for the item; verify the deployment with `npx rayfin up status`.
192
166
 
193
167
  ## See also
194
168
 
169
+ - [Functions](./functions/index.md) — read secrets from server-side functions with `ctx.getSecret`.
195
170
  - [CLI quickstart](./quickstart.md)
196
171
  - [Environment configuration](./env-interpolation.md)
@@ -0,0 +1,39 @@
1
+ ---
2
+ sidebar_position: 5
3
+ ---
4
+
5
+ # Add Azure DevOps
6
+
7
+ Call the [Azure DevOps REST API](https://learn.microsoft.com/en-us/rest/api/azure/devops/) from a function **as the signed-in user**, using `AudienceType.ADO`.
8
+
9
+ Provide your Azure DevOps **organization** (and project, if the call needs one) — e.g. `https://dev.azure.com/<org>`. The token is a standard bearer token — send it with `fetch`:
10
+
11
+ ```ts
12
+ import {
13
+ UserDataFunctions,
14
+ AudienceType,
15
+ type RayfinContext,
16
+ } from "@microsoft/fabric-user-data-functions";
17
+
18
+ const udf = new UserDataFunctions();
19
+
20
+ // Use your real organization URL.
21
+ const ORG = "https://dev.azure.com/<org>";
22
+
23
+ udf.func(
24
+ "listProjects",
25
+ async (ctx: RayfinContext): Promise<unknown> => {
26
+ const token = ctx.getToken(AudienceType.ADO);
27
+ const res = await fetch(`${ORG}/_apis/projects?api-version=7.1`, {
28
+ headers: { Authorization: `Bearer ${token}` },
29
+ });
30
+ if (!res.ok) {
31
+ throw new Error(`Azure DevOps returned ${res.status}`);
32
+ }
33
+ return res.json();
34
+ },
35
+ [udf.connection({ audienceType: AudienceType.ADO })],
36
+ );
37
+ ```
38
+
39
+ See [Connecting to external resources](./index.md) for the shared connection model.