Fabric icon indicating copy to clipboard operation
Fabric copied to clipboard

[Feature request]: External Template Extensions Proposal

Open mattjoyce opened this issue 1 year ago • 10 comments

What do you need?

External Template Extensions Proposal

Overview

Propose adding an external extension system to Fabric that allows users to extend functionality through custom executables while maintaining security through configuration-based verification.

Goals

  1. Enable custom integrations with external systems (databases, APIs, tools)
  2. Maintain security through verified extensions
  3. Leverage existing template system
  4. Support multi-language extension development
  5. Enable complex automation workflows

Benefits

##For Project

Architecture Evolution: Enables moving all extensions external, including current hard-coded features (if desirable), supporting better modularity Independent Development: Teams can maintain their own extensions without coordinating with core Fabric development Rapid Integration: Add new capabilities without modifying Fabric core Extensible Framework: Opens path for new extension types (e.g., output plugins for Obsidian integration) Separation of Concerns: Cleaner core codebase focused on essential functionality

For Users

Private Customization: Create personal extensions without requiring dev team oversight or sharing Technology Choice: Write extensions in any programming language, using familiar tools and libraries Direct Control: Implement custom integrations for personal or organization-specific needs

Extensions System Design

Template Syntax

{{ext:alias:operation:param1|param2|param3}}

Examples:
{{ext:prod-mysql:query:SELECT * FROM users|analytics}}
{{ext:jira:tickets:PROJECT-123}}
{{ext:github:commits:main|last-week}}

Extension Definition (YAML)

name: mysql-plugin      
binary: /usr/local/bin/mysql-plugin
type: executable       
args_format: "-q {1} -d {2}"  
description: "MySQL database query plugin"
author: "Jane Doe"
version: "1.0.0"
env:
  - MYSQL_USER
  - MYSQL_PASS

Security Model

  1. Extension Registration
  • Extensions must be registered in Fabric's config
  • Both config and binary hashes are verified
  • Only approved extensions can execute
  1. Configuration in ~/.config/fabric/extensions.yaml

# Extension Registration
``` yaml
enabled: 
  MYSQL_PROD: 
    config_path: /etc/fabric/extensions/mysql-prod.yaml 
    config_hash: sha256:e234f7... 
    binary_hash: sha256:45de9d... 
disabled:
  JIRA_DEV: 
    config_path: /etc/fabric/extensions/jira-dev.yaml 
    config_hash: sha256:8abc23... 
    binary_hash: sha256:9def45...
  1. Integrity Verification
  • SHA-256 used for both config and binary verification
  • Hashes checked before each extension execution
  • Performance impact negligible compared to LLM latency
  • Prevents tampering with approved extensions
  1. Extension Management
# Register new extensions
fabric --addextension ~/extensions/mysql-extension.yaml

# List registered extensions
fabric --listextensions

# Remove extensions
fabric --rmextensions mysql-extension

Use Cases

  1. Data Integration
{{ext:database:query|SELECT metrics FROM systems}}
{{ext:api:fetch|/endpoint/data}}
  1. Tool Integration
{{ext:git:diff|main}}
{{ext:docker:status}}
  1. Meta-Operations

Run fabric in fabric.

{{ext:fabric:analyze|{{input}}}}
{{ext:fabric:summarize|{{output}}}}

No LLM mode

  • Optional mode where Fabric only processes templates
  • No LLM calls made
  • Useful for testing extensions and automation
  • fabric --nollm --pattern my-pattern

Security Considerations

  1. Trust Boundary
  • Moves from "trust all executables" to "trust registered extension"
  • Security controlled through configuration in .config/fabric
  • Existing file permissions protect extension registry
  1. Extension Execution
  • Runs with user permissions
  • Environment variables controlled through extension config
  • No shell interpolation in command execution
  1. Configuration Protection
  • ~/.config/fabric/.env already contains sensitive data
  • Standard Unix file permissions apply
  • Single source of truth for extension authorization
  1. Limitations
  • Extension run with user permissions
  • No sandboxing implemented
  • Trust model relies on extension review and registration
  • 3rd party binaries, will inevitably be updated, causing hashes to fail, and require re-registration. (might need a n update hash command)

Implementation Notes

  1. Extensions Resolution
  • Check if extension alias exists in extensions.yaml
  • Verify both config and binary hashes
  • Load extension configuration
  • Execute with provided parameters
  1. Hash Verification
  • SHA-256 used for integrity checking
  • Hashes computed and verified on each execution
  • Performance impact minimal (milliseconds)
  1. Error Handling
  • Clear error messages for missing extenions
  • Hash verification failures prevent execution
  • Extensions execution errors captured and reported - hmm - maybe

Future Considerations

  1. Extension Distribution
  • Central repository of verified extensions
  • Automated updates and verification
  • Version management
  1. Enhanced Security
  • Optional sandboxing
  • Resource limitations
  • More granular permissions
  1. Extension Development
  • Extension templates
  • Development guidelines
  • Testing framework

Security Review Questions

  1. Is the trust model appropriate for the use case?
  2. Are there additional controls needed for extension execution?
  3. Should extension binary locations be restricted?
  4. Are there risks in the template parameter passing?
  5. Should there be additional restrictions on environment variables?

mattjoyce avatar Nov 24 '24 09:11 mattjoyce

Changes term to be be 'extension'. Template extension. Extends the templating system.

mattjoyce avatar Nov 24 '24 22:11 mattjoyce

@eugeis I started looking at this

propose plugin/template/extension.go plugin/template/extension_reg.go plugin/template/extension_exec.go plugin/template/hash.go (there is no global utils package)

mattjoyce avatar Nov 24 '24 22:11 mattjoyce

@mattjoyce what do you think about to use something from here?

eugeis avatar Nov 25 '24 12:11 eugeis

@eugeis , really interesting. I'm not a confident Go coder, there's lot's I'm unfamiliar with. One of my goals for this proposal, was to allow extension to decouple from Go, so that folk who use Python, Powershell, etc, can make an extension. I think this will connect fabric to other project domains, like IOT, Active Directory, llama-index and such.

My understanding from the list of Go plugin packages is they allow runtime loading of other Go, which really good for keeping the project from becoming bloated, but it's a barrier for non-Go coders to leverage Fabric.

My thoughts with the ad-hoc patterns from files, the template system and now extensions, is to somewhat decouple the core of fabric, from the need for curation by the project team, and provide a way to fabric to play nicely with other systems.

Your thoughts?

mattjoyce avatar Nov 26 '24 21:11 mattjoyce

@mattjoyce I really like your design idea overall! I was just considering some aspects like general performance, integration efforts, and data parsing/conversion. For added flexibility, it might be helpful to include an option for extensions. This way, we can observe which types of extensions are most commonly used and later implement native solutions or plugins for those that prove particularly valuable. Therefore I would say, please proceed with your impl.

eugeis avatar Nov 27 '24 11:11 eugeis

I think performance is possibly quite variable. Spawning external executables and making requests..etc Ah I see, so if a particular extension becomes high utility, we can work on a Go implementation. I get it.

I have nearly finish a prototype. For now I will sort extension configs in a ~/.config/fabric/extensions.yaml also limiting results back via stdout from the extension, or to a temp file. as this results are destined for llm contect, even 100k token window is ~400kb file.

here's the extension config struct

type ExtensionDefinition struct {
	Name        string   `yaml:"name"`
	Executable  string   `yaml:"executable"`
	Type        string   `yaml:"type"`
	CmdTemplate string   `yaml:"cmd_template"`  
	Output      struct {
			Method     string `yaml:"method"`
			Format     string `yaml:"format"`
			FileConfig *struct {
					Cleanup        bool `yaml:"cleanup"`
					PathFromStdout bool `yaml:"path_from_stdout"`
			} `yaml:"file_config,omitempty"`
	} `yaml:"output"`
	Description string   `yaml:"description"`
	Author      string   `yaml:"author"`
	Version     string   `yaml:"version"`
	Env         []string `yaml:"env"`
}

mattjoyce avatar Nov 27 '24 12:11 mattjoyce

@eugeis , I think it pretty much done. I have some example extensions, and I think I will add some docs. shall I put them /plugins/template/examples ?

mattjoyce avatar Dec 05 '24 09:12 mattjoyce

@mattjoyce yes, please. I would happy to test it :-)

eugeis avatar Dec 05 '24 09:12 eugeis

@eugeis , I have added an Examples folder with a short tutorial. Hope it all makes sense. Actually pretty fun.

https://github.com/mattjoyce/fabric/tree/feature/template-extensions

mattjoyce avatar Dec 05 '24 11:12 mattjoyce

@mattjoyce, I like it very much. Would you like create a PR?

eugeis avatar Dec 23 '24 12:12 eugeis

Closed via #1227

ksylvan avatar Sep 30 '25 20:09 ksylvan