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

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.
Files changed (30) hide show
  1. package/assets/docs/{experimental/cli → cli}/connectors/add.md +2 -0
  2. package/assets/docs/{experimental/cli → cli}/connectors/category-a-entities.md +1 -1
  3. package/assets/docs/{experimental/cli → cli}/connectors/category-b-function-bridge.md +38 -12
  4. package/assets/docs/cli/connectors/eventhouse.md +21 -0
  5. package/assets/docs/{experimental/cli → cli}/connectors/index.md +7 -22
  6. package/assets/docs/{experimental/cli → cli}/connectors/invoke.md +4 -0
  7. package/assets/docs/{experimental/cli → cli}/connectors/search.md +4 -2
  8. package/assets/docs/cli/environment-variables.md +2 -2
  9. package/assets/docs/cli/functions/deploy.md +38 -0
  10. package/assets/docs/cli/functions/dev-apply.md +62 -0
  11. package/assets/docs/cli/functions/index.md +41 -0
  12. package/assets/docs/cli/functions/init.md +62 -0
  13. package/assets/docs/cli/index.md +35 -1
  14. package/assets/docs/cli/secrets.md +97 -122
  15. package/assets/docs/cli/templates.md +7 -0
  16. package/assets/docs/functions/connections/add-ado.md +39 -0
  17. package/assets/docs/functions/connections/add-azure-resource.md +171 -0
  18. package/assets/docs/functions/connections/add-fabric-resource.md +186 -0
  19. package/assets/docs/functions/connections/add-foundry.md +46 -0
  20. package/assets/docs/functions/connections/add-work-iq.md +39 -0
  21. package/assets/docs/functions/connections/get-fabric-info.md +159 -0
  22. package/assets/docs/functions/connections/index.md +89 -0
  23. package/assets/docs/functions/index.md +91 -0
  24. package/assets/docs/functions/invoking-from-frontend.md +94 -0
  25. package/assets/docs/functions/secrets.md +70 -0
  26. package/assets/docs/functions/typegen.md +44 -0
  27. package/assets/docs/functions/writing-functions.md +140 -0
  28. package/assets/docs/getting-started/project-structure.md +91 -2
  29. package/package.json +1 -1
  30. /package/assets/docs/{experimental/cli → cli}/connectors/inspect.md +0 -0
@@ -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)
@@ -20,6 +20,13 @@ Every `npm create @microsoft/rayfin@latest` or `npx rayfin init` invocation can
20
20
  External and local template sources are discovered through `rayfin-template.yml` manifests inside the selected source directory.
21
21
  Built-in templates are packaged with the CLI and appear in `--list-templates` automatically.
22
22
 
23
+ > **Universal App is distributed by the Rayfin Copilot plugin.**
24
+ > It is a hidden built-in template: it does not appear in `--list-templates`,
25
+ > but it can be selected explicitly with `--template universal-app`.
26
+ > The plugin selects that bundled template and distributes its committed workspace
27
+ > template directly.
28
+ > This does not change support for ordinary local directories, git repositories, or registered templates.
29
+
23
30
  ## List available templates
24
31
 
25
32
  Use `--list-templates` to see every template the CLI can scaffold from in your current directory:
@@ -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.
@@ -0,0 +1,171 @@
1
+ ---
2
+ sidebar_position: 3
3
+ ---
4
+
5
+ # Add an Azure resource
6
+
7
+ Connect a function to an **Azure service** — Key Vault, Cosmos DB, Blob Storage, or Event Grid — and call it **as the signed-in user**.
8
+
9
+ These are Azure resources, not Fabric items, so their endpoints come from the **Azure portal** (there is no Fabric lookup). Each pattern declares the connection, reads the token with `ctx.getToken()`, and wraps it with the [`ContextTokenCredential`](./index.md#wrapping-the-token-for-azure-sdk-clients) helper for the Azure SDK. See [Connecting to external resources](./index.md) for the shared model.
10
+
11
+ ## Key Vault
12
+
13
+ Read secrets from Azure Key Vault using `AudienceType.KeyVault`.
14
+
15
+ ```bash
16
+ cd rayfin/functions
17
+ npm install @azure/keyvault-secrets @azure/identity
18
+ ```
19
+
20
+ ```ts
21
+ import {
22
+ UserDataFunctions,
23
+ AudienceType,
24
+ type RayfinContext,
25
+ } from "@microsoft/fabric-user-data-functions";
26
+ import { SecretClient } from "@azure/keyvault-secrets";
27
+
28
+ const udf = new UserDataFunctions();
29
+
30
+ udf.func(
31
+ "getVaultSecret",
32
+ async (
33
+ ctx: RayfinContext,
34
+ kvUrl: string,
35
+ secretName: string,
36
+ ): Promise<string> => {
37
+ const credential = new ContextTokenCredential(
38
+ ctx.getToken(AudienceType.KeyVault),
39
+ );
40
+ const client = new SecretClient(kvUrl, credential);
41
+ const secret = await client.getSecret(secretName);
42
+ return secret.value ?? "";
43
+ },
44
+ [udf.connection({ audienceType: AudienceType.KeyVault })],
45
+ );
46
+ ```
47
+
48
+ Provide the vault URL (e.g. `https://my-vault.vault.azure.net/`).
49
+
50
+ > To read secrets stored with Rayfin itself (rather than an external Key Vault), use [`ctx.getSecret()`](../secrets.md) instead — no connection required.
51
+
52
+ ## Cosmos DB
53
+
54
+ Connect to Azure Cosmos DB using `AudienceType.CosmosDB`. Pass the credential as `aadCredentials`:
55
+
56
+ ```bash
57
+ cd rayfin/functions
58
+ npm install @azure/cosmos
59
+ ```
60
+
61
+ ```ts
62
+ import {
63
+ UserDataFunctions,
64
+ AudienceType,
65
+ type RayfinContext,
66
+ } from "@microsoft/fabric-user-data-functions";
67
+ import { CosmosClient } from "@azure/cosmos";
68
+
69
+ const udf = new UserDataFunctions();
70
+
71
+ udf.func(
72
+ "readItems",
73
+ async (
74
+ ctx: RayfinContext,
75
+ endpoint: string,
76
+ databaseId: string,
77
+ containerId: string,
78
+ ): Promise<unknown[]> => {
79
+ const credential = new ContextTokenCredential(
80
+ ctx.getToken(AudienceType.CosmosDB),
81
+ );
82
+ const client = new CosmosClient({ endpoint, aadCredentials: credential });
83
+ const { resources } = await client
84
+ .database(databaseId)
85
+ .container(containerId)
86
+ .items.readAll()
87
+ .fetchAll();
88
+ return resources;
89
+ },
90
+ [udf.connection({ audienceType: AudienceType.CosmosDB })],
91
+ );
92
+ ```
93
+
94
+ Provide the account endpoint and the database / container names.
95
+
96
+ ## Blob Storage
97
+
98
+ Connect to Azure Blob / Table / Queue storage using `AudienceType.Storage`:
99
+
100
+ ```bash
101
+ cd rayfin/functions
102
+ npm install @azure/storage-blob
103
+ ```
104
+
105
+ ```ts
106
+ import { BlobServiceClient } from "@azure/storage-blob";
107
+
108
+ udf.func(
109
+ "listBlobs",
110
+ async (ctx: RayfinContext, accountUrl: string): Promise<string[]> => {
111
+ const credential = new ContextTokenCredential(
112
+ ctx.getToken(AudienceType.Storage),
113
+ );
114
+ const service = new BlobServiceClient(accountUrl, credential);
115
+ const names: string[] = [];
116
+ for await (const container of service.listContainers()) {
117
+ names.push(container.name);
118
+ }
119
+ return names;
120
+ },
121
+ [udf.connection({ audienceType: AudienceType.Storage })],
122
+ );
123
+ ```
124
+
125
+ Provide the storage account URL (e.g. `https://<account>.blob.core.windows.net`).
126
+
127
+ > `AudienceType.Storage` also covers **OneLake** files — that Fabric case is documented in [Add a Fabric resource → OneLake files](./add-fabric-resource.md#onelake-files).
128
+
129
+ ## Event Grid
130
+
131
+ Publish events to an Azure Event Grid topic using `AudienceType.EventGrid`. The topic endpoint is in the Azure portal → your topic → **Overview** → _Topic Endpoint_.
132
+
133
+ ```bash
134
+ cd rayfin/functions
135
+ npm install @azure/eventgrid
136
+ ```
137
+
138
+ ```ts
139
+ import {
140
+ UserDataFunctions,
141
+ AudienceType,
142
+ type RayfinContext,
143
+ } from "@microsoft/fabric-user-data-functions";
144
+ import { EventGridPublisherClient } from "@azure/eventgrid";
145
+
146
+ const udf = new UserDataFunctions();
147
+
148
+ const TOPIC_ENDPOINT =
149
+ "https://<topic>.<region>.eventgrid.azure.net/api/events";
150
+
151
+ udf.func(
152
+ "publishEvent",
153
+ async (ctx: RayfinContext, subject: string): Promise<string> => {
154
+ const client = new EventGridPublisherClient(
155
+ TOPIC_ENDPOINT,
156
+ "EventGrid",
157
+ new ContextTokenCredential(ctx.getToken(AudienceType.EventGrid)),
158
+ );
159
+ await client.send([
160
+ {
161
+ eventType: "Rayfin.Function.Event",
162
+ subject,
163
+ dataVersion: "1.0",
164
+ data: { source: "user-data-function" },
165
+ },
166
+ ]);
167
+ return "published";
168
+ },
169
+ [udf.connection({ audienceType: AudienceType.EventGrid })],
170
+ );
171
+ ```