From 8333672683ff102b9d9d912b3e99b5a0718bd741 Mon Sep 17 00:00:00 2001 From: Rob Colbert Date: Tue, 5 May 2026 08:12:34 -0400 Subject: [PATCH] platform.apiKey becomes platform.gadgetKey gadget-drone now presents an ApiClient _id value as the Gadget Key, allowing gadget-code to reference the client, determine the associated User, and invoke logic on the User's behalf as an authenticated and authorized client. --- docs/configuration.md | 41 +++++++++++---------------- gadget-code/src/config/env.ts | 9 +++--- gadget-code/src/web-cli.ts | 8 +++++- gadget-drone/src/config/env.ts | 10 +++---- gadget-drone/src/services/platform.ts | 8 +++--- packages/config/src/loader.ts | 9 +++--- packages/config/src/types.ts | 2 +- 7 files changed, 44 insertions(+), 43 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 3ade668..c4d2d86 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -77,12 +77,12 @@ site: # Authentication (REQUIRED) auth: - jwtSecret: "${DTP_JWT_SECRET}" # Required - passwordSalt: "${DTP_USER_PASSWORD_SALT}" # Required + jwtSecret: "${DTP_JWT_SECRET}" # Required + passwordSalt: "${DTP_USER_PASSWORD_SALT}" # Required # Session configuration (REQUIRED) session: - secret: "${DTP_SESSION_SECRET}" # Required + secret: "${DTP_SESSION_SECRET}" # Required trustProxy: true cookie: secure: true @@ -113,7 +113,7 @@ https: # Socket.IO configuration socket: - maxHttpBufferSize: 10485760 # 10MB + maxHttpBufferSize: 10485760 # 10MB # Logging configuration logging: @@ -121,7 +121,7 @@ logging: enabled: true file: enabled: true - path: "~/.local/state/gadget-code/logs" # Supports ~ for home directory + path: "~/.local/state/gadget-code/logs" # Supports ~ for home directory name: "gadget-code" https: enabled: true @@ -176,8 +176,8 @@ timezone: "America/New_York" # Platform connection (REQUIRED) platform: - baseUrl: "https://code.example.com:3443" # Required - apiKey: "${GADGET_PLATFORM_KEY}" # Required + baseUrl: "https://code.example.com:3443" # Required + apiKey: "${GADGET_PLATFORM_KEY}" # Required # Logging configuration logging: @@ -302,6 +302,7 @@ gadget-drone ``` Each drone will: + - Have its own unique workspace ID (stored in `.gadget/workspace.json`) - Register separately with the platform - Process work orders independently @@ -320,15 +321,15 @@ Copy your `.env` values to the appropriate YAML file using the examples above. Map your old `.env` variable names to the new YAML structure: -| Old .env Variable | New YAML Path | -|-------------------|---------------| -| `DTP_JWT_SECRET` | `auth.jwtSecret` | -| `DTP_USER_PASSWORD_SALT` | `auth.passwordSalt` | -| `DTP_SESSION_SECRET` | `session.secret` | -| `DTP_MONGODB_HOST` | `mongodb.host` | -| `DTP_REDIS_HOST` | `redis.host` | -| `GADGET_PLATFORM_URL` | `platform.baseUrl` | -| `GADGET_PLATFORM_KEY` | `platform.apiKey` | +| Old .env Variable | New YAML Path | +| ------------------------ | -------------------- | +| `DTP_JWT_SECRET` | `auth.jwtSecret` | +| `DTP_USER_PASSWORD_SALT` | `auth.passwordSalt` | +| `DTP_SESSION_SECRET` | `session.secret` | +| `DTP_MONGODB_HOST` | `mongodb.host` | +| `DTP_REDIS_HOST` | `redis.host` | +| `GADGET_PLATFORM_URL` | `platform.baseUrl` | +| `GADGET_PLATFORM_KEY` | `platform.gadgetKey` | ### 3. Set Environment Variables @@ -419,11 +420,3 @@ node -e "console.log(require('js-yaml').load(require('fs').readFileSync('~/.conf 3. **Use HTTPS in production**: Always enable HTTPS for the web server 4. **Restrict database access**: Configure MongoDB and Redis to only accept local connections 5. **Rotate secrets regularly**: Update JWT secrets, password salts, and API keys periodically - -## Support - -For issues or questions: - -- **Documentation**: https://github.com/anomalyco/gadget/tree/main/docs -- **Issues**: https://github.com/anomalyco/gadget/issues -- **Discussions**: https://github.com/anomalyco/gadget/discussions diff --git a/gadget-code/src/config/env.ts b/gadget-code/src/config/env.ts index 43fb243..b6280e0 100644 --- a/gadget-code/src/config/env.ts +++ b/gadget-code/src/config/env.ts @@ -19,19 +19,19 @@ const yamlConfig = loadGadgetCodeConfig(); if (!yamlConfig.auth?.jwtSecret) { throw new Error( "Configuration error: auth.jwtSecret is required in gadget-code.yaml\n" + - "See documentation: https://github.com/anomalyco/gadget/blob/main/docs/configuration.md", + "See documentation: ./docs/configuration.md", ); } if (!yamlConfig.auth?.passwordSalt) { throw new Error( "Configuration error: auth.passwordSalt is required in gadget-code.yaml\n" + - "See documentation: https://github.com/anomalyco/gadget/blob/main/docs/configuration.md", + "See documentation: ./docs/configuration.md", ); } if (!yamlConfig.session?.secret) { throw new Error( "Configuration error: session.secret is required in gadget-code.yaml\n" + - "See documentation: https://github.com/anomalyco/gadget/blob/main/docs/configuration.md", + "See documentation: ./docs/configuration.md", ); } @@ -66,7 +66,8 @@ export default { companyShort: yamlConfig.site?.companyShort || "Colbert", name: yamlConfig.site?.name || "Gadget Code", shortName: yamlConfig.site?.shortName || "Gadget Code", - slogan: yamlConfig.site?.slogan || "Self-hosted Agentic Engineering Platform", + slogan: + yamlConfig.site?.slogan || "Self-hosted Agentic Engineering Platform", description: yamlConfig.site?.description || "Gadget Code - A self-hosted Agentic Engineering Platform (AEP).", diff --git a/gadget-code/src/web-cli.ts b/gadget-code/src/web-cli.ts index bbbaa0e..ea3e496 100644 --- a/gadget-code/src/web-cli.ts +++ b/gadget-code/src/web-cli.ts @@ -190,7 +190,13 @@ class DtpWebCli extends DtpProcess { } printApiClientList(clients: IApiClient[]) { - console.log("Name".padEnd(20), "Client ID".padEnd(24), "Secret"); + console.log( + "Name".padEnd(20), + "Gadget Key".padEnd(21), + "Secret".padEnd(36), + "User ID".padEnd(21), + "Email", + ); console.log( "--------------------------------------------------------------------------------", ); diff --git a/gadget-drone/src/config/env.ts b/gadget-drone/src/config/env.ts index cf232a0..a6e1be2 100644 --- a/gadget-drone/src/config/env.ts +++ b/gadget-drone/src/config/env.ts @@ -19,13 +19,13 @@ const yamlConfig = loadGadgetDroneConfig(); if (!yamlConfig.platform?.baseUrl) { throw new Error( "Configuration error: platform.baseUrl is required in gadget-drone.yaml\n" + - "See documentation: https://github.com/anomalyco/gadget/blob/main/docs/configuration.md", + "See documentation: ./docs/configuration.md", ); } -if (!yamlConfig.platform?.apiKey) { +if (!yamlConfig.platform?.gadgetKey) { throw new Error( - "Configuration error: platform.apiKey is required in gadget-drone.yaml\n" + - "See documentation: https://github.com/anomalyco/gadget/blob/main/docs/configuration.md", + "Configuration error: platform.gadgetKey is required in gadget-drone.yaml\n" + + "See documentation: ./docs/configuration.md", ); } @@ -45,7 +45,7 @@ export default { ), platform: { baseUrl: yamlConfig.platform.baseUrl, - apiKey: yamlConfig.platform.apiKey, + gadgetKey: yamlConfig.platform.gadgetKey, }, log: { console: { diff --git a/gadget-drone/src/services/platform.ts b/gadget-drone/src/services/platform.ts index 67f1ff4..aad45ba 100644 --- a/gadget-drone/src/services/platform.ts +++ b/gadget-drone/src/services/platform.ts @@ -74,7 +74,7 @@ class PlatformService extends GadgetService { Accept: "application/json", "Content-Type": "application/json", "Content-Length": body.length.toString(), - "X-Gadget-Key": env.platform.apiKey, + "X-Gadget-Key": env.platform.gadgetKey, }, body, }); @@ -122,7 +122,7 @@ class PlatformService extends GadgetService { Accept: "application/json", "Content-Type": "application/json", "Content-Length": body.length.toString(), - "X-Gadget-Key": env.platform.apiKey, + "X-Gadget-Key": env.platform.gadgetKey, }, body, }); @@ -152,7 +152,7 @@ class PlatformService extends GadgetService { Accept: "application/json", "Content-Type": "application/json", "Content-Length": body.length.toString(), - "X-Gadget-Key": env.platform.apiKey, + "X-Gadget-Key": env.platform.gadgetKey, }, body, }); @@ -181,7 +181,7 @@ class PlatformService extends GadgetService { method: "GET", headers: { Accept: "application/json", - "X-Gadget-Key": env.platform.apiKey, + "X-Gadget-Key": env.platform.gadgetKey, }, }); diff --git a/packages/config/src/loader.ts b/packages/config/src/loader.ts index 230b337..49e6c00 100644 --- a/packages/config/src/loader.ts +++ b/packages/config/src/loader.ts @@ -50,9 +50,10 @@ function processConfigValues(obj: unknown): unknown { * Search for configuration file in standard locations. * Order: ~/.config/gadget/ first, then /etc/gadget/ */ -export function searchConfigFile( - configName: string, -): { path: string; exists: boolean } { +export function searchConfigFile(configName: string): { + path: string; + exists: boolean; +} { const homeConfigDir = path.join(os.homedir(), ".config", "gadget"); const systemConfigDir = "/etc/gadget"; @@ -87,7 +88,7 @@ export function loadYamlConfig(configName: string): T { ` - ${path.join(os.homedir(), ".config", "gadget", configName)}\n` + ` - /etc/gadget/${configName}\n\n` + `Please create a configuration file. See documentation at:\n` + - ` https://github.com/anomalyco/gadget/blob/main/docs/configuration.md`, + ` ./docs/configuration.md`, ); error.name = "ConfigNotFoundError"; throw error; diff --git a/packages/config/src/types.ts b/packages/config/src/types.ts index 8334e85..796ea95 100644 --- a/packages/config/src/types.ts +++ b/packages/config/src/types.ts @@ -118,7 +118,7 @@ export interface GadgetDroneConfig { timezone?: string; platform: { baseUrl: string; - apiKey: string; + gadgetKey: string; }; logging?: { console?: {