-
Notifications
You must be signed in to change notification settings - Fork 2
spike(do-not-merge): Add session-scoped public/private key encryption for remote secrets (MVP) #149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Important Review skippedBot user detected. To trigger a single review, invoke the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. ✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
👋 Welcome to the Airbyte Connector Builder MCP!Thank you for your contribution! Here are some helpful tips and reminders for your convenience. Testing This Branch via MCPTo test the changes in this specific branch with an MCP client like Claude Desktop, use the following configuration: {
"mcpServers": {
"connector-builder-mcp-dev": {
"command": "uvx",
"args": ["--from", "git+https://github.com/airbytehq/connector-builder-mcp.git@copilot/add-session-scoped-key-encryption", "connector-builder-mcp"]
}
}
}Testing This Branch via CLIYou can test this version of the MCP Server using the following CLI snippet: # Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/connector-builder-mcp.git@copilot/add-session-scoped-key-encryption#egg=airbyte-connector-builder-mcp' --helpPR Slash CommandsAirbyte Maintainers can execute the following slash commands on your PR:
AI Builder EvaluationsAI builder evaluations run automatically under the following conditions:
A set of standardized evaluations also run on a schedule (Mon/Wed/Fri at midnight UTC) and can be manually triggered via workflow dispatch. Helpful ResourcesIf you have any questions, feel free to ask in the PR comments or join our Slack community. |
Co-authored-by: aaronsteers <[email protected]>
Co-authored-by: aaronsteers <[email protected]>
Co-authored-by: aaronsteers <[email protected]>
|
@copilot - Let's make the libsodium implementation compatible with the prior secret URIs as input args. Let's implement |
To clarify the implementation: should Option A - File-based: Where the file contains JSON: Option B - Inline: Where the ciphertext when decrypted contains dotenv format content. Which approach do you prefer? I'm leaning toward Option A as it's more consistent with how privatebin URLs work.
Implemented the Key changes:
Usage: # Create encrypted file with dotenv content
# File: /path/to/secrets.sealed
# {"kid": "abc123", "ciphertext": "encrypted-dotenv-content"}
# Use with salt-sealed URI
config = hydrate_config(
base_config,
dotenv_file_uris="salt-sealed:/path/to/secrets.sealed"
)
# Can combine with regular dotenv files
config = hydrate_config(
base_config,
dotenv_file_uris=[
"/path/to/config.env",
"salt-sealed:/path/to/secrets.sealed"
]
)The encrypted file's content (after decryption) should be in dotenv format with support for dot notation (e.g., |
…rameter - Add salt-sealed: URI support for encrypted secrets files - Remove encrypted_secrets parameter from hydrate_config() - Salt-sealed files contain JSON with kid and ciphertext - After decryption, content is parsed as dotenv format - Update tests to use salt-sealed URI approach - Update documentation with new usage examples Co-authored-by: aaronsteers <[email protected]>
Session-Scoped Public/Private Key Encryption for Remote Secrets (MVP)
This PR implements session-scoped encryption for remote secrets, allowing users to encrypt secrets client-side before sending them to the MCP server. This ensures plaintext secrets are never exposed to the LLM or persisted on the server.
Features
Session-Scoped Keypair Generation
mcp+session://encryption/pubkeykid(key ID) for validationClient-Side Encryption with salt-sealed: URIs
Users can encrypt secrets on their own machine and use them with the
salt-sealed:URI prefix:salt-sealed:/absolute/path/to/file.sealed{"kid": "...", "ciphertext": "..."}Decrypt-On-Use Flow
Security Model
Implementation Details
Algorithm Choice
Selected libsodium sealed-box (X25519 + XSalsa20-Poly1305) for:
Feature Flag
Encryption is disabled by default via the
ENABLE_SESSION_ENCRYPTIONenvironment variable:export ENABLE_SESSION_ENCRYPTION=true uvx airbyte-connector-builder-mcpThis ensures backward compatibility and allows users to opt-in when they need the extra security.
New Components
connector_builder_mcp/encryption.py(252 lines):initialize_session_keypair(): Generate new keypair on startupdestroy_session_keypair(): Clean up on shutdowndecrypt_secret(): Decrypt with validation and error handlingget_public_key_info(): Retrieve public key detailsencrypt_for_testing(): Test helper (not for production use)docs/encryption.md(217 lines):Modified Components
connector_builder_mcp/server.py:connector_builder_mcp/secrets.py:salt-sealed:URI support for encrypted secrets_is_salt_sealed_url(),_fetch_salt_sealed_content()_validate_secrets_uris()to validate salt-sealed URIs_load_secrets()to handle salt-sealed URIs with dot notation parsingget_encryption_instructions()tool for user guidanceSecurity Guarantees
✅ No plaintext at rest: Secrets decrypted only when needed, immediately discarded
✅ No logging: Secrets never appear in logs
✅ Session-scoped: Keypairs destroyed on server shutdown
✅ Buffer zeroization: Plaintext buffers cleared (to extent Python allows)
✅ Size limits: 64 KB maximum ciphertext size
✅ Kid validation: Rejects ciphertext from wrong session
✅ Clear errors: Helpful messages for invalid ciphertext, kid mismatch, size violations
✅ Absolute paths: Salt-sealed URIs require absolute paths for security
Testing
Usage Example
Non-Goals (Future Work)
This MVP focuses on the core encryption infrastructure. Future enhancements may include:
Dependencies
Added PyNaCl (v1.5.0+) for libsodium bindings:
Documentation
docs/encryption.md: Complete user guide with salt-sealed examplesREADME.md: Updated to mention encryption featureRecent Changes
get_encryption_instructions()to use constant strings defined at the top ofsecrets.pyfor better maintainabilitysalt-sealed:URI prefix: Replaced separateencrypted_secretsparameter with URI-based approach compatible with existing dotenv URI systemFixes #147
Original prompt
Fixes #147
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.