Creating Secure Tools
Build marketplace tools that execute on your own servers while keeping API keys and credentials private.
What are Secure Tools?
Secure tools are marketplace items that execute remotely on a provider's server instead of being downloaded as DLLs to consumer hosts. This model is ideal when your tool needs:
- API keys or credentials — Users provide their own keys, which go directly to your server. Daisinet never stores them.
- Proprietary logic — Your code runs on your infrastructure, protecting intellectual property.
- External service access — Your server can call third-party APIs, databases, or other services directly.
- Server-side state — Maintain user sessions, caches, or data that persists between invocations.
How It Works
The architecture uses an InstallId — an opaque identifier generated on purchase — for all provider-facing communication. No Daisinet account IDs are ever sent to providers.
- Purchase — When a user buys your tool, the ORC generates an
InstallIdand calls your/installendpoint to register the installation. - Configure — The user enters their credentials in the Manager UI, which sends them directly to your server (not through the ORC) with the
InstallId. - Execute — During inference, the consumer host calls your
/executeendpoint with aSessionIdand parameters. Your server validates the session by calling back to the ORC, which returns the resolvedInstallIdandBundleInstallId. - Uninstall — When a purchase is deactivated, the ORC calls your
/uninstallendpoint so you can clean up stored data.
InstallId directly,
meaning any host that learned an InstallId could impersonate the installation. With session-based validation, the host only
knows the ephemeral SessionId. The provider validates it with the ORC, which returns the real InstallId
only to your authenticated server. This keeps the InstallId private between the ORC and the provider.
Step 1: Implement the Provider API
Your server must implement four POST endpoints:
POST /install ORC-originated
Called by the ORC when a user purchases your tool. Register the installation. For bundled tools, a shared bundleInstallId is included.
// Request
Headers: X-Daisi-Auth: {sharedSecret}
Body: {
"installId": "inst-260215143022-abcdef",
"toolId": "weather-lookup",
"bundleInstallId": "binst-260215143022-shared" // optional, present for bundled tools
}
// Response
{ "success": true }
POST /uninstall ORC-originated
Called by the ORC when a purchase is deactivated. Clean up stored data for this installation.
// Request
Headers: X-Daisi-Auth: {sharedSecret}
Body: { "installId": "inst-260215143022-abcdef" }
// Response
{ "success": true }
POST /configure Consumer-originated
Receives user setup data (API keys, credentials) directly from the Manager UI. Store these securely.
// Request (no X-Daisi-Auth header)
Body: {
"installId": "inst-260215143022-abcdef",
"toolId": "weather-lookup",
"setupValues": { "apiKey": "sk-...", "region": "US" }
}
// Response
{ "success": true }
POST /execute Consumer-originated
Executes the tool with the given parameters. Called directly by consumer hosts with a sessionId instead of an installId. Your server must validate the session by calling the ORC before executing.
// Request from consumer host (no X-Daisi-Auth header)
Body: {
"sessionId": "sess-260218120000-xyz789",
"toolId": "weather-lookup",
"parameters": [ { "name": "city", "value": "San Francisco" } ]
}
// Step 1: Provider validates session with ORC
POST {OrcValidationUrl}/api/secure-tools/validate
Headers: X-Daisi-Auth: {sharedSecret}
Body: { "sessionId": "sess-260218120000-xyz789", "toolId": "weather-lookup" }
// ORC response
{ "valid": true, "installId": "inst-260215143022-abcdef", "bundleInstallId": "binst-260215143022-shared" }
// Step 2: Provider executes using the resolved installId
// Response to consumer host
{
"success": true,
"output": "72 F, Sunny",
"outputFormat": "plaintext",
"outputMessage": "Current weather for San Francisco"
}
Auth model:
/installand/uninstall— Verify theX-Daisi-Authheader matches your shared secret. These come from the ORC./configure— Verify that theinstallIdwas registered via/install. No shared secret header is sent — theinstallIdis an opaque, unguessable identifier that serves as a bearer token./execute— Receives asessionIdfrom the consumer host. Validate it by callingPOST {OrcValidationUrl}/api/secure-tools/validatewith yourX-Daisi-Authheader. The ORC returns the resolvedinstallIdandbundleInstallId. Use theinstallIdto look up stored configuration and execute the tool.
Step 2: Create the Marketplace Item
- In the DAISI Manager, navigate to Marketplace > Provider Dashboard > Create New Item.
- Set the Item Type to Host Tool.
- Enable the Secure Execution toggle.
- Fill in:
- Endpoint URL — Your server's base URL (e.g.
https://my-func.azurewebsites.net/api) - Auth Key — A shared secret the ORC will send as
X-Daisi-Authfor install/uninstall - Tool ID — Unique identifier (e.g.
my-weather-tool) - Tool Name — Display name for the AI (e.g.
Weather Lookup) - Use Instructions — Natural language description of when/how the AI should use this tool
- Tool Group — Category for filtering (e.g. Information Tools, Integration Tools)
- Execution Cost — Optional credit cost per execution. If set, consumers are charged this amount each time the tool is invoked. The cost is snapshotted at execution time, so changing it later does not affect past records. Leave blank or set to 0 for no per-execution charge.
- Call Parameters — Parameters the AI provides at execution time
- Setup Parameters — Fields users fill in during configuration (API keys, regions, etc.)
- Endpoint URL — Your server's base URL (e.g.
- Submit for review. An admin will verify your endpoint is reachable and responds correctly.
Step 3: Reference Implementation
A reference Azure Functions implementation is provided in the daisi-tools-dotnet/SecureToolProvider directory.
It demonstrates:
- Installation registration and cleanup (
/install,/uninstall) - Auth header verification for ORC-originated calls
- InstallId validation for consumer-originated calls
- Setup data storage and retrieval
- Parameter handling and response formatting
- Error handling for missing configuration or unknown installations
Clone the reference project and replace the echo logic with your actual tool implementation.
OAuth Integration
For tools that integrate with services like Office 365, Google, or X, use OAuth setup parameters instead of manual API key entry. The tool provider owns the entire OAuth lifecycle — Daisinet's role is limited to rendering a "Connect" button and checking connection status.
When to use OAuth vs API keys
- API keys — When the user already has a key or can generate one from a service dashboard. Simpler to implement.
- OAuth — When the service requires user consent via a browser flow (e.g. Microsoft Graph, Google APIs, X/Twitter API v2).
How to define an OAuth setup parameter
When creating your marketplace item, add a setup parameter with type oauth and fill in:
- AuthUrl — Your provider's OAuth initiation endpoint (e.g.
https://your-api.com/api/auth/start) - ServiceLabel — Display label shown on the Connect button (e.g. "Office 365", "Google")
The OAuth flow
[Configure Page]
User clicks "Connect to [ServiceLabel]"
--> Manager opens popup to provider's AuthUrl
--> Provider redirects to external OAuth consent screen
--> User authorizes
--> External provider redirects to provider's /auth/callback
--> Provider stores tokens, redirects popup to Daisinet's /marketplace/oauth-callback
--> Popup shows "Connection Successful" and auto-closes
--> Manager polls provider's /auth/status until connected
--> Green "Connected" badge appears
Required provider endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/auth/start | GET | Initiates OAuth flow. Receives installId, returnUrl, service as query params. Redirects to external consent screen. |
/auth/callback | GET | Handles OAuth callback from external provider. Exchanges code for tokens, stores them, redirects popup to returnUrl. |
/auth/status | POST | Returns connection status. Receives { installId, service }, returns { connected, serviceName, userLabel }. |
Security notes
- The provider registers their own OAuth app with external services and manages all client credentials.
- Daisinet never sees OAuth tokens, client secrets, or refresh tokens.
- The ORC has zero involvement in OAuth — no tokens, no client credentials, no refresh logic.
- Hosts remain untrusted and never see tokens.
Bundle OAuth: Shared Authentication
When you publish a Plugin that bundles multiple secure tools from the same provider, users shouldn't have to OAuth-connect each tool separately. Daisinet supports BundleInstallId — a shared identifier that lets you key OAuth tokens at the bundle level.
How it works
- Purchase — When a user buys a Plugin with bundled secure tools, the ORC generates a shared
BundleInstallId(prefixedbinst-) in addition to each tool's ownInstallId. - Install notification — Your
/installendpoint receives bothinstallIdandbundleInstallId. Store the mapping. - OAuth — When keying OAuth tokens, use
bundleInstallId(if present) instead ofinstallId. This way, authenticating from any tool in the bundle makes all sibling tools show "Connected". - Non-OAuth setup — API keys and other per-tool configuration still use the tool's own
InstallId, keeping them independent.
// /install request for a bundled tool
{
"installId": "inst-260215143022-abcdef",
"toolId": "calendar-tool",
"bundleInstallId": "binst-260215143022-shared" // shared across bundle
}
// OAuth token keying
key = bundleInstallId ?? installId;
oauthTokens[$"{key}:google"] = tokens;
// Non-OAuth setup — always per-tool
setupData[installId] = { "apiKey": "sk-..." };
The reference implementation in daisi-tools-dotnet/SecureToolProvider demonstrates this pattern via the SetupStore class,
which maintains a bundle map and resolves OAuth keys to the bundle level automatically.
Output Formats
The outputFormat field in the execute response determines how the output is rendered:
| Value | Description |
|---|---|
plaintext | Plain text (default) |
json | JSON data |
markdown | Markdown formatted text |
html | HTML content |
base64 | Base64 encoded binary data |