Skip to content

feat(fn-secrets): add package for resolving function secrets from database#48

Open
theothersideofgod wants to merge 5 commits into
mainfrom
feat/fn-secrets-package
Open

feat(fn-secrets): add package for resolving function secrets from database#48
theothersideofgod wants to merge 5 commits into
mainfrom
feat/fn-secrets-package

Conversation

@theothersideofgod
Copy link
Copy Markdown
Contributor

@theothersideofgod theothersideofgod commented May 20, 2026

Summary

  • Add @constructive-io/fn-secrets package for resolving encrypted secrets at runtime via GraphQL
  • Supports per-tenant secret overrides with fallback to global defaults

Changes

Commit 1: feat(fn-secrets): add package

  • resolveSecrets(context, functionName) — returns SecretsMap for easy use
  • resolveSecretsRaw(options) — returns full secret details with source
  • 10 unit tests covering all error cases

Commit 2: refactor(fn-secrets): reuse context.client

  • resolveSecrets() now uses context.client with per-request header override
  • Add schemata option for custom schema access (default: infra_private,infra_public)
  • resolveSecretsRaw() still creates standalone client for direct usage
  • 11 tests total (added header override verification)

API

import { resolveSecrets } from '@constructive-io/fn-secrets';

// In a function handler:
const secrets = await resolveSecrets(context, 'send-sms');
// → { TWILIO_ACCOUNT_SID: 'AC...', TWILIO_AUTH_TOKEN: '...' }

// With custom options:
const secrets = await resolveSecrets(context, 'send-sms', {
  schemata: 'custom_private,custom_public'
});

Test Plan

  • Unit tests pass (11 tests)
  • Integration test with live GraphQL server
  • Verify secret resolution for send-sms function

🤖 Generated with Claude Code

…abase

Adds @constructive-io/fn-secrets package that enables cloud functions to
resolve encrypted secrets at runtime via GraphQL. Supports per-tenant
secret overrides with fallback to global defaults.

- resolveSecrets(context, functionName) - returns SecretsMap
- resolveSecretsRaw() - returns full secret details with source
- 10 unit tests covering all error cases

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
theothersideofgod and others added 2 commits May 21, 2026 13:12
Instead of creating a new GraphQL client for each resolveSecrets() call,
reuse the existing context.client and override headers via the third
argument to client.request(). This enables dynamic schema access via
X-Schemata header without duplicating client setup logic.

- resolveSecrets() now uses context.client
- Add schemata option for custom schema override
- resolveSecretsRaw() still creates standalone client for direct usage
- Update tests to verify header override behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 21, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​agentic-kit/​ollama@​1.2.07410010089100
Addednpm/​makage@​0.3.07610010093100
Addednpm/​@​constructive-io/​graphql-query@​3.25.57710010098100

View full report

@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 21, 2026

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm markdown-it is 91.0% likely obfuscated

Confidence: 0.91

Location: Package overview

From: pnpm-lock.yamlnpm/markdown-it@14.1.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/markdown-it@14.1.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

- Replace require() with ESM import and MockedClass pattern
- Convert jest.config.js to jest.config.cjs for CommonJS compat

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comment thread packages/fn-secrets/package.json Outdated
"author": "Constructive <developers@constructive.io>",
"license": "MIT",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't use dist/ like this! see our pnpm constructive-skills

and fix ALL packages that do this please


const RESOLVE_SECRETS_QUERY = `
query ResolveSecrets(
$functionId: UUID!
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this even a real GraphQL option in our code?

/** @type {import('jest').Config} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this .cjs? can it be like our other packages in other repos?

- Change package.json to use main/types pointing to dist root
- Add publishConfig.directory: "dist" for npm publishing
- Switch from tsc to makage build
- Rename jest.config.cjs to jest.config.js

Follows constructive-pnpm skill guidelines for TypeScript packages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@theothersideofgod
Copy link
Copy Markdown
Contributor Author

Thanks for the review! Fixed in bec6bf7:

1. package.json structure

  • Changed to dist-folder publishing pattern per constructive-pnpm skill
  • main: "index.js", types: "index.d.ts", publishConfig.directory: "dist"
  • Switched to makage build

2. GraphQL queries

  • defaultFunctionDefinitions exists: constructive-db/packages/infra/schemas/infra_public/tables/default_function_definitions/
  • resolveFunctionSecrets exists: constructive-db/packages/infra-secrets/schemas/infra_private/procedures/resolve_function_secrets.sql

3. jest.config.cjs → jest.config.js

  • Renamed to match ecosystem pattern

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants