Files
kandev/backend/internal/agent/credentials/env_provider.go
T
jcfs ba919305c2 Initial commit: Kandev with SQLite persistence and agent integration
Features:
- Unified Go binary running Task Service, Agent Manager, and Orchestrator
- SQLite persistence for boards, columns, and tasks
- Docker-based agent execution with ACP message streaming
- Augment Agent integration with session resumption support
- RESTful API for all operations (port 8080)
- In-memory event bus for service communication

Architecture:
- cmd/kandev: Single entry point for all services
- internal/task: Task, board, and column management
- internal/agent: Docker container lifecycle and ACP streaming
- internal/orchestrator: Agent coordination and monitoring
- internal/events: In-memory pub/sub event bus

Documentation:
- README.md: Project overview and quick start
- docs/ARCHITECTURE.md: System architecture (current + planned)
- docs/GETTING_STARTED.md: Development setup guide
- docs/IMPLEMENTATION_PLAN.md: Original microservices plan
- backend/NEXT_STEPS.md: Development roadmap
2026-01-10 01:30:24 +00:00

136 lines
3.0 KiB
Go

package credentials
import (
"context"
"fmt"
"os"
"strings"
)
// knownAPIKeyPatterns contains patterns for known API key environment variables
var knownAPIKeyPatterns = []string{
"ANTHROPIC_API_KEY",
"OPENAI_API_KEY",
"GEMINI_API_KEY",
"GOOGLE_API_KEY",
"AZURE_OPENAI_API_KEY",
"COHERE_API_KEY",
"HUGGINGFACE_API_KEY",
"MISTRAL_API_KEY",
"TOGETHER_API_KEY",
"REPLICATE_API_TOKEN",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"GCP_SERVICE_ACCOUNT_KEY",
"GITHUB_TOKEN",
"GITLAB_TOKEN",
"BITBUCKET_TOKEN",
"NPM_TOKEN",
"DOCKER_PASSWORD",
"DOCKER_TOKEN",
}
// EnvProvider provides credentials from environment variables
type EnvProvider struct {
prefix string // Optional prefix filter (e.g., "KANDEV_")
}
// NewEnvProvider creates a new environment provider
func NewEnvProvider(prefix string) *EnvProvider {
return &EnvProvider{
prefix: prefix,
}
}
// Name returns the provider name
func (p *EnvProvider) Name() string {
return "environment"
}
// GetCredential retrieves a credential from environment variables
func (p *EnvProvider) GetCredential(ctx context.Context, key string) (*Credential, error) {
// First try exact key
value := os.Getenv(key)
if value != "" {
return &Credential{
Key: key,
Value: value,
Source: "environment",
}, nil
}
// Try with prefix
if p.prefix != "" {
prefixedKey := p.prefix + key
value = os.Getenv(prefixedKey)
if value != "" {
return &Credential{
Key: key,
Value: value,
Source: "environment",
}, nil
}
}
return nil, fmt.Errorf("credential not found: %s", key)
}
// ListAvailable returns list of available credential keys from environment
func (p *EnvProvider) ListAvailable(ctx context.Context) ([]string, error) {
available := make([]string, 0)
// Check known API key patterns
for _, pattern := range knownAPIKeyPatterns {
// Check exact match
if os.Getenv(pattern) != "" {
available = append(available, pattern)
continue
}
// Check with prefix
if p.prefix != "" && os.Getenv(p.prefix+pattern) != "" {
available = append(available, pattern)
}
}
// Also scan environment for any variables ending in common patterns
for _, env := range os.Environ() {
parts := strings.SplitN(env, "=", 2)
if len(parts) != 2 || parts[1] == "" {
continue
}
key := parts[0]
// Skip if already in list
found := false
for _, existing := range available {
if existing == key {
found = true
break
}
}
if found {
continue
}
// Check for API key patterns in environment variable names
lowerKey := strings.ToLower(key)
if strings.Contains(lowerKey, "api_key") ||
strings.Contains(lowerKey, "apikey") ||
strings.Contains(lowerKey, "api-key") ||
strings.Contains(lowerKey, "_token") ||
strings.Contains(lowerKey, "_secret") {
// Strip prefix if present
if p.prefix != "" && strings.HasPrefix(key, p.prefix) {
key = strings.TrimPrefix(key, p.prefix)
}
available = append(available, key)
}
}
return available, nil
}