permfs

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 12, 2025 License: MIT Imports: 17 Imported by: 0

README

permfs

Go Reference Go Report Card CI License

Fine-grained access control and permission enforcement for the AbsFS filesystem abstraction layer.

Overview

permfs provides a powerful permission layer for filesystem operations, enabling fine-grained access control with support for path-based rules, Access Control Lists (ACLs), and comprehensive audit logging. It wraps any absfs.FileSystem implementation and enforces security policies before delegating operations to the underlying filesystem.

absfs.FileSystem Compliance

permfs provides full absfs.FileSystem compliance through the AbsAdapter type. The adapter bridges permfs's context-aware design with the standard absfs interface:

import (
    "github.com/absfs/absfs"
    "github.com/absfs/permfs"
)

// Create a permission-controlled filesystem
pfs, _ := permfs.New(baseFS, config)

// Wrap in an adapter to get absfs.FileSystem compatibility
adapter := permfs.NewAbsAdapter(pfs, "alice")  // Pre-configured identity

// Now use it anywhere absfs.FileSystem is expected
var fs absfs.FileSystem = adapter
f, _ := fs.Open("/home/alice/file.txt")
Context Handling Strategy

permfs uses context for identity propagation, while absfs does not support context. The AbsAdapter resolves this by:

  1. Stored Context: The adapter maintains an internal context with user identity
  2. SetIdentity(): Change the identity at runtime for different operations
  3. SetContext(): Provide a full custom context for advanced use cases
adapter := permfs.NewAbsAdapter(pfs, "alice")

// Operations run as alice
adapter.Open("/home/alice/file.txt")

// Switch to bob
adapter.SetIdentity("bob", []string{"developers"}, nil)
adapter.Open("/projects/code.go")

// Use full context control
ctx := permfs.WithUserGroupsAndRoles(context.Background(),
    "charlie", []string{"admins"}, []string{"superuser"})
adapter.SetContext(ctx)

Key features:

  • Path-based permission rules with wildcard support
  • Access Control Lists (ACLs) with user/group/role permissions
  • Operation-level control (read, write, execute, delete, metadata)
  • Audit logging for compliance and security monitoring
  • Multi-tenant support with isolated permission contexts
  • Integration with authentication systems (OAuth, JWT, custom)
  • Performance-optimized with rule caching and lazy evaluation

Permission Model

Permission Levels

permfs operates on a hierarchical permission model:

  1. Operation Types

    • Read: Open files for reading, list directories
    • Write: Create, modify, or append to files
    • Execute: Execute files (relevant for executable files)
    • Delete: Remove files or directories
    • Metadata: Read/modify file attributes, permissions, timestamps
    • Admin: Full control including permission changes
  2. Access Control Entries (ACEs)

    • Subject: User ID, Group ID, Role, or wildcard
    • Resource: Path pattern (supports wildcards: *, **, ?)
    • Permission: Allow or Deny
    • Operations: Bitmap of allowed operations
    • Priority: For conflict resolution (higher priority wins)
  3. Evaluation Order

    1. Explicit deny rules (highest priority)
    2. Explicit allow rules
    3. Inherited permissions from parent paths
    4. Default deny (secure by default)
ACL Structure
type ACL struct {
    Entries []ACLEntry
    Default Permission // Applied when no rules match
}

type ACLEntry struct {
    Subject     Subject         // Who
    PathPattern string          // What (supports glob patterns)
    Permissions OperationSet    // Which operations
    Effect      Effect          // Allow or Deny
    Priority    int             // Conflict resolution
    Conditions  []Condition     // Optional conditions (time, IP, etc.)
}

type Subject struct {
    Type SubjectType // User, Group, Role, Everyone
    ID   string
}

type OperationSet uint32 // Bitmask of operations
Path Pattern Matching
  • /data/user123/** - All files under user123 directory
  • /public/*.txt - All .txt files in public directory
  • /temp/**/*.log - All log files anywhere under temp
  • /home/*/documents/** - Documents for any user

Implementation Phases

Phase 1: Core Permission Engine

Foundation

  • ACL data structures and parsing
  • Path pattern matcher with wildcard support
  • Permission evaluation engine
  • Context propagation (user identity, request metadata)

Basic Operations

  • File operation interceptors (Open, Create, Remove, etc.)
  • Permission checks before delegation
  • Error handling and reporting

Testing

  • Unit tests for rule evaluation
  • Pattern matching test suite
  • Permission conflict resolution tests
Phase 2: Advanced ACL Features

Enhancements

  • Group and role-based permissions
  • Permission inheritance and override
  • Time-based access (temporal conditions)
  • IP/network-based restrictions
  • Custom condition evaluators

Caching

  • Rule evaluation result cache
  • Path pattern compilation cache
  • LRU cache with TTL support
Phase 3: Audit and Monitoring

Audit Logging

  • Structured audit logs (JSON, syslog)
  • Configurable verbosity levels
  • Log rotation and retention
  • Async logging for performance

Events

  • Access granted/denied events
  • Policy violations
  • Administrative actions
  • Real-time event streaming

Metrics

  • Permission check latency
  • Cache hit rates
  • Access patterns and hotspots
  • Security metrics (failed access attempts)
Phase 4: Integration and Management

Authentication Integration

  • JWT token validation
  • OAuth/OIDC integration
  • API key authentication
  • Custom authenticator interface

Management API

  • Dynamic rule updates (no restart required)
  • Rule validation and testing
  • Permission queries ("what can user X do?")
  • Bulk operations for rule management

Policy Import/Export

  • JSON/YAML policy files
  • Version control friendly formats
  • Policy migration tools
  • Template-based policies
Phase 5: Advanced Features

Multi-tenancy

  • Isolated permission contexts per tenant
  • Tenant-level policy inheritance
  • Cross-tenant resource sharing
  • Quota and rate limiting integration

Delegation

  • Temporary permission grants
  • Delegated administration
  • Service account permissions
  • Impersonation controls

Compliance

  • Read-only mode enforcement
  • Immutability guarantees
  • Retention policies
  • Compliance reporting

API Design

Basic Usage
package main

import (
    "github.com/absfs/absfs"
    "github.com/absfs/permfs"
    "github.com/absfs/osfs"
)

func main() {
    // Wrap any filesystem
    base := osfs.New("/data")

    // Create permission layer
    fs, err := permfs.New(base, permfs.Config{
        ACL: permfs.ACL{
            Entries: []permfs.ACLEntry{
                {
                    Subject:     permfs.User("alice"),
                    PathPattern: "/home/alice/**",
                    Permissions: permfs.ReadWrite,
                    Effect:      permfs.Allow,
                },
                {
                    Subject:     permfs.Group("admins"),
                    PathPattern: "/**",
                    Permissions: permfs.All,
                    Effect:      permfs.Allow,
                },
            },
            Default: permfs.Deny,
        },
    })

    // Use with context containing user identity
    ctx := permfs.WithUser(context.Background(), "alice")

    // Operations are automatically checked
    f, err := fs.OpenFile(ctx, "/home/alice/file.txt", os.O_RDWR, 0644)
    if err != nil {
        // Will fail if alice doesn't have permission
        log.Fatal(err)
    }
    defer f.Close()
}
Dynamic Rule Management
// Add rule at runtime
err := fs.AddRule(permfs.ACLEntry{
    Subject:     permfs.User("bob"),
    PathPattern: "/shared/**",
    Permissions: permfs.Read,
    Effect:      permfs.Allow,
    Priority:    100,
})

// Remove rule
fs.RemoveRule(ruleID)

// Query permissions
perms, err := fs.GetPermissions(ctx, "/shared/file.txt", "bob")
if perms.CanRead() {
    // Bob can read this file
}

// List effective rules for a path
rules := fs.GetEffectiveRules("/shared/data.json")
Audit Configuration
fs, err := permfs.New(base, permfs.Config{
    Audit: permfs.AuditConfig{
        Enabled: true,
        Writer:  os.Stdout, // Or custom writer
        Format:  permfs.JSON,
        Level:   permfs.AuditAll, // Log all access attempts
        Fields: []string{
            "timestamp", "user", "operation",
            "path", "result", "duration",
        },
    },
})

// Audit log example:
// {"timestamp":"2024-01-15T10:30:00Z","user":"alice","operation":"Open",
//  "path":"/data/secret.txt","result":"denied","reason":"insufficient_permissions"}
Rule Engine API
// Create custom condition
fs.RegisterCondition("business_hours", func(ctx context.Context) bool {
    hour := time.Now().Hour()
    return hour >= 9 && hour <= 17
})

// Use in ACL
acl := permfs.ACL{
    Entries: []permfs.ACLEntry{
        {
            Subject:     permfs.User("contractor"),
            PathPattern: "/company/**",
            Permissions: permfs.Read,
            Effect:      permfs.Allow,
            Conditions: []permfs.Condition{
                permfs.TimeCondition("business_hours"),
            },
        },
    },
}

Usage Examples

Multi-tenant Application
type TenantFS struct {
    perms map[string]*permfs.FileSystem
}

func (t *TenantFS) GetFS(tenantID string) (absfs.FileSystem, error) {
    if fs, ok := t.perms[tenantID]; ok {
        return fs, nil
    }

    // Create tenant-specific permissions
    acl := permfs.ACL{
        Entries: []permfs.ACLEntry{
            {
                Subject:     permfs.Group(tenantID + ":users"),
                PathPattern: fmt.Sprintf("/tenants/%s/**", tenantID),
                Permissions: permfs.ReadWrite,
                Effect:      permfs.Allow,
            },
            {
                Subject:     permfs.Everyone(),
                PathPattern: fmt.Sprintf("/tenants/%s/**", tenantID),
                Permissions: permfs.All,
                Effect:      permfs.Deny,
            },
        },
    }

    fs, err := permfs.New(t.baseFS, permfs.Config{ACL: acl})
    t.perms[tenantID] = fs
    return fs, err
}
Shared File System with Groups
// Engineering team can read/write to /projects
// Managers can read everything
// Interns can only read /public
acl := permfs.ACL{
    Entries: []permfs.ACLEntry{
        {
            Subject:     permfs.Group("engineering"),
            PathPattern: "/projects/**",
            Permissions: permfs.ReadWrite,
            Effect:      permfs.Allow,
            Priority:    100,
        },
        {
            Subject:     permfs.Group("managers"),
            PathPattern: "/**",
            Permissions: permfs.Read | permfs.Metadata,
            Effect:      permfs.Allow,
            Priority:    50,
        },
        {
            Subject:     permfs.Role("intern"),
            PathPattern: "/public/**",
            Permissions: permfs.Read,
            Effect:      permfs.Allow,
            Priority:    10,
        },
    },
    Default: permfs.Deny,
}
Read-only Archive with Exceptions
// Most files are read-only
// Admins can write to /admin
// Metadata service can update timestamps
acl := permfs.ACL{
    Entries: []permfs.ACLEntry{
        {
            Subject:     permfs.Group("admins"),
            PathPattern: "/admin/**",
            Permissions: permfs.All,
            Effect:      permfs.Allow,
            Priority:    1000,
        },
        {
            Subject:     permfs.User("metadata-service"),
            PathPattern: "/**",
            Permissions: permfs.Metadata,
            Effect:      permfs.Allow,
            Priority:    500,
        },
        {
            Subject:     permfs.Everyone(),
            PathPattern: "/**",
            Permissions: permfs.Read,
            Effect:      permfs.Allow,
            Priority:    1,
        },
    },
}

Integration with Authentication Systems

JWT Integration
// Extract user identity from JWT token
func JWTAuthenticator(tokenString string) (*permfs.Identity, error) {
    token, err := jwt.Parse(tokenString, keyFunc)
    if err != nil {
        return nil, err
    }

    claims := token.Claims.(jwt.MapClaims)
    return &permfs.Identity{
        UserID: claims["sub"].(string),
        Groups: claims["groups"].([]string),
        Roles:  claims["roles"].([]string),
        Metadata: map[string]string{
            "email": claims["email"].(string),
        },
    }, nil
}

// Use with permfs
fs := permfs.NewWithAuthenticator(base, config, JWTAuthenticator)
ctx := permfs.WithToken(context.Background(), jwtToken)
OAuth/OIDC
// Configure OIDC provider
oidcProvider, err := oidc.NewProvider(ctx, "https://accounts.example.com")
verifier := oidcProvider.Verifier(&oidc.Config{ClientID: clientID})

authenticator := func(token string) (*permfs.Identity, error) {
    idToken, err := verifier.Verify(ctx, token)
    if err != nil {
        return nil, err
    }

    var claims struct {
        Sub    string   `json:"sub"`
        Email  string   `json:"email"`
        Groups []string `json:"groups"`
    }
    if err := idToken.Claims(&claims); err != nil {
        return nil, err
    }

    return &permfs.Identity{
        UserID: claims.Sub,
        Groups: claims.Groups,
        Metadata: map[string]string{"email": claims.Email},
    }, nil
}
Custom Authentication
type CustomAuthenticator struct {
    userDB UserDatabase
}

func (a *CustomAuthenticator) Authenticate(ctx context.Context) (*permfs.Identity, error) {
    // Extract credentials from context
    apiKey := ctx.Value("api-key").(string)

    // Validate and lookup user
    user, err := a.userDB.GetUserByAPIKey(apiKey)
    if err != nil {
        return nil, err
    }

    return &permfs.Identity{
        UserID: user.ID,
        Groups: user.Groups,
        Roles:  user.Roles,
    }, nil
}

Audit Logging

Structured Logging
type AuditEvent struct {
    Timestamp   time.Time         `json:"timestamp"`
    RequestID   string            `json:"request_id"`
    UserID      string            `json:"user_id"`
    Operation   string            `json:"operation"`
    Path        string            `json:"path"`
    Result      string            `json:"result"` // "allowed" or "denied"
    Reason      string            `json:"reason,omitempty"`
    Duration    time.Duration     `json:"duration_ms"`
    Metadata    map[string]string `json:"metadata,omitempty"`
}

// Custom audit handler
fs, err := permfs.New(base, permfs.Config{
    Audit: permfs.AuditConfig{
        Handler: func(event permfs.AuditEvent) {
            // Send to SIEM, log aggregator, etc.
            siem.Send(event)

            // Alert on suspicious activity
            if event.Result == "denied" && event.UserID == "admin" {
                security.Alert("Admin access denied", event)
            }
        },
    },
})
Audit Queries
// Query audit logs
events, err := fs.AuditLog().Query(permfs.AuditQuery{
    StartTime: time.Now().Add(-24 * time.Hour),
    UserID:    "alice",
    Operation: "Delete",
    Result:    "denied",
})

// Export for compliance
fs.AuditLog().Export("/var/log/audit/permfs-2024-01.jsonl")

Performance Considerations

Caching Strategy
  • Rule compilation cache: Pre-compiled path patterns (regex/glob)
  • Permission evaluation cache: Results cached per (user, path, operation)
  • ACL lookup cache: Fast access to applicable rules
  • Default TTL: 5 minutes (configurable)
  • Cache invalidation: On rule updates or explicit flush
Performance Optimizations
fs, err := permfs.New(base, permfs.Config{
    Performance: permfs.PerformanceConfig{
        // Enable caching
        CacheEnabled:     true,
        CacheTTL:         5 * time.Minute,
        CacheMaxSize:     10000,

        // Lazy evaluation
        LazyEvaluation:   true,

        // Async audit logging
        AsyncAudit:       true,
        AuditBufferSize:  1000,

        // Rule optimization
        CompilePatterns:  true,
        OptimizeRules:    true,
    },
})
Benchmarks

Expected performance (with caching):

  • Permission check: < 100 microseconds
  • Rule evaluation: < 50 microseconds
  • Cache hit rate: > 95% for typical workloads
  • Overhead vs raw filesystem: < 5% for cached operations
Scalability
  • Support for 10,000+ concurrent users
  • 100,000+ permission rules
  • Million+ files per second (cached operations)
  • Horizontal scaling via stateless design

Testing

// Use in tests with mock users
func TestFileAccess(t *testing.T) {
    fs := permfs.NewTestFS(t, permfs.TestConfig{
        Users: []string{"alice", "bob"},
        Groups: map[string][]string{
            "admin": {"alice"},
            "users": {"bob"},
        },
        ACL: testACL,
    })

    ctx := permfs.WithUser(context.Background(), "alice")

    // Test access
    f, err := fs.OpenFile(ctx, "/admin/config.json", os.O_RDONLY, 0)
    require.NoError(t, err)
    defer f.Close()

    // Test denial
    ctx = permfs.WithUser(context.Background(), "bob")
    _, err = fs.OpenFile(ctx, "/admin/config.json", os.O_RDONLY, 0)
    require.Error(t, err)
    require.True(t, permfs.IsPermissionDenied(err))
}

License

MIT License - see LICENSE file for details

Contributing

Contributions welcome! Please see the AbsFS contribution guidelines.

  • absfs - Core filesystem abstraction
  • basefs - Base filesystem wrapper utilities
  • lockfs - Concurrent access control
  • rofs - Read-only filesystem wrapper

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrPermissionDenied is returned when a permission check fails
	ErrPermissionDenied = errors.New("permission denied")

	// ErrNoIdentity is returned when no identity is found in context
	ErrNoIdentity = errors.New("no identity in context")

	// ErrInvalidPattern is returned when a path pattern is invalid
	ErrInvalidPattern = errors.New("invalid path pattern")

	// ErrInvalidConfig is returned when configuration is invalid
	ErrInvalidConfig = errors.New("invalid configuration")
)

Common permission combinations

View Source
var (
	Allow = EffectAllow
	Deny  = EffectDeny
)

Functions

func AddMetadata

func AddMetadata(ctx context.Context, key string, value interface{}) context.Context

AddMetadata adds a key-value pair to the context metadata

func GetMetadata

func GetMetadata(ctx context.Context) map[string]interface{}

GetMetadata extracts metadata from the context

func GetRequestID

func GetRequestID(ctx context.Context) string

GetRequestID retrieves the request ID from the context

func GetToken

func GetToken(ctx context.Context) (string, bool)

GetToken extracts the authentication token from the context

func IsPermissionDenied

func IsPermissionDenied(err error) bool

IsPermissionDenied checks if an error is a permission denial

func NewPermissionError

func NewPermissionError(path string, op Operation, userID string, reason string) error

NewPermissionError creates a new permission error

func SavePolicy

func SavePolicy(policy *PolicyFile, w io.Writer, format PolicyFormat) error

SavePolicy saves a policy to a writer

func SavePolicyToFile

func SavePolicyToFile(policy *PolicyFile, filename string, format PolicyFormat) error

SavePolicyToFile saves a policy to a file

func WithIdentity

func WithIdentity(ctx context.Context, identity *Identity) context.Context

WithIdentity returns a new context with the given identity

func WithMetadata

func WithMetadata(ctx context.Context, metadata map[string]interface{}) context.Context

WithMetadata returns a new context with additional metadata

func WithRequestID

func WithRequestID(ctx context.Context, requestID string) context.Context

WithRequestID adds a request ID to the context

func WithToken

func WithToken(ctx context.Context, token string) context.Context

WithToken returns a new context with an authentication token The token can be used by authenticators to extract identity

func WithUser

func WithUser(ctx context.Context, userID string) context.Context

WithUser returns a new context with a simple user identity

func WithUserAndGroups

func WithUserAndGroups(ctx context.Context, userID string, groups []string) context.Context

WithUserAndGroups returns a new context with a user identity including groups

func WithUserGroupsAndRoles

func WithUserGroupsAndRoles(ctx context.Context, userID string, groups, roles []string) context.Context

WithUserGroupsAndRoles returns a new context with a complete user identity

Types

type ACL

type ACL struct {
	// Entries is the list of ACL rules
	Entries []ACLEntry
	// Default is the default effect when no rules match
	Default Effect
}

ACL represents a complete access control list

func ImportPolicy

func ImportPolicy(policy *PolicyFile) (ACL, error)

ImportPolicy imports a policy file into an ACL

func OptimizeACL

func OptimizeACL(acl ACL) ACL

OptimizeACL optimizes an ACL by removing redundant rules

type ACLEntry

type ACLEntry struct {
	// Subject specifies who this rule applies to
	Subject Subject
	// PathPattern is a glob pattern matching filesystem paths
	PathPattern string
	// Permissions specifies which operations are allowed/denied
	Permissions Operation
	// Effect specifies whether to allow or deny access
	Effect Effect
	// Priority is used for conflict resolution (higher priority wins)
	Priority int
	// Conditions are optional conditions that must be satisfied
	Conditions []Condition
}

ACLEntry represents a single access control rule

func (ACLEntry) Applies

func (e ACLEntry) Applies(op Operation) bool

Applies checks if this entry's permissions apply to the requested operation

func (ACLEntry) Matches

func (e ACLEntry) Matches(ctx *EvaluationContext) bool

Matches checks if this entry applies to the given context

func (ACLEntry) String

func (e ACLEntry) String() string

String returns a string representation of the ACL entry

type APIKeyAuthenticator

type APIKeyAuthenticator struct {
	// contains filtered or unexported fields
}

APIKeyAuthenticator authenticates using API keys

func NewAPIKeyAuthenticator

func NewAPIKeyAuthenticator() *APIKeyAuthenticator

NewAPIKeyAuthenticator creates a new API key authenticator

func (*APIKeyAuthenticator) AddAPIKey

func (aka *APIKeyAuthenticator) AddAPIKey(apiKey string, identity *Identity)

AddAPIKey adds an API key

func (*APIKeyAuthenticator) Authenticate

func (aka *APIKeyAuthenticator) Authenticate(ctx context.Context) (*Identity, error)

Authenticate extracts identity from context using API key

func (*APIKeyAuthenticator) AuthenticateToken

func (aka *APIKeyAuthenticator) AuthenticateToken(apiKey string) (*Identity, error)

AuthenticateToken validates an API key

type AbsAdapter

type AbsAdapter struct {
	// contains filtered or unexported fields
}

AbsAdapter wraps a PermFS to implement absfs.FileSystem interface. It stores a context internally which is used for all permission checks. The context can be updated via SetContext or SetIdentity methods.

func NewAbsAdapter

func NewAbsAdapter(pfs *PermFS, identity *Identity) *AbsAdapter

NewAbsAdapter creates a new absfs.FileSystem compatible wrapper around PermFS. The provided identity will be used for all permission checks. If identity is nil, all operations will fail with ErrNoIdentity until an identity is set.

func NewAbsAdapterWithContext

func NewAbsAdapterWithContext(pfs *PermFS, ctx context.Context) *AbsAdapter

NewAbsAdapterWithContext creates a new absfs.FileSystem compatible wrapper using the provided context for permission checks.

func (*AbsAdapter) Chdir

func (a *AbsAdapter) Chdir(dir string) error

Chdir changes the current working directory.

func (*AbsAdapter) Chmod

func (a *AbsAdapter) Chmod(name string, mode os.FileMode) error

Chmod changes the mode of the named file.

func (*AbsAdapter) Chown

func (a *AbsAdapter) Chown(name string, uid, gid int) error

Chown changes the numeric uid and gid of the named file.

func (*AbsAdapter) Chtimes

func (a *AbsAdapter) Chtimes(name string, atime time.Time, mtime time.Time) error

Chtimes changes the access and modification times of the named file.

func (*AbsAdapter) Create

func (a *AbsAdapter) Create(name string) (absfs.File, error)

Create creates or truncates the named file.

func (*AbsAdapter) Getwd

func (a *AbsAdapter) Getwd() (string, error)

Getwd returns the current working directory.

func (*AbsAdapter) Lchown

func (a *AbsAdapter) Lchown(name string, uid, gid int) error

Lchown changes the numeric uid and gid of the named file without following symlinks. Note: This delegates to Chown as the underlying filesystem may not support Lchown.

func (*AbsAdapter) Lstat

func (a *AbsAdapter) Lstat(name string) (os.FileInfo, error)

Lstat returns file info without following symlinks.

func (*AbsAdapter) Mkdir

func (a *AbsAdapter) Mkdir(name string, perm os.FileMode) error

Mkdir creates a directory.

func (*AbsAdapter) MkdirAll

func (a *AbsAdapter) MkdirAll(name string, perm os.FileMode) error

MkdirAll creates a directory and all parent directories.

func (*AbsAdapter) Open

func (a *AbsAdapter) Open(name string) (absfs.File, error)

Open opens the named file for reading.

func (*AbsAdapter) OpenFile

func (a *AbsAdapter) OpenFile(name string, flag int, perm os.FileMode) (absfs.File, error)

OpenFile opens a file with the specified flags and permissions.

func (*AbsAdapter) PermFS

func (a *AbsAdapter) PermFS() *PermFS

PermFS returns the underlying PermFS instance.

func (*AbsAdapter) ReadDir

func (a *AbsAdapter) ReadDir(name string) ([]fs.DirEntry, error)

ReadDir reads the named directory and returns directory entries.

func (*AbsAdapter) ReadFile

func (a *AbsAdapter) ReadFile(name string) ([]byte, error)

ReadFile reads the named file and returns its contents.

func (a *AbsAdapter) Readlink(name string) (string, error)

Readlink returns the destination of the named symbolic link.

func (*AbsAdapter) Remove

func (a *AbsAdapter) Remove(name string) error

Remove removes a file or empty directory.

func (*AbsAdapter) RemoveAll

func (a *AbsAdapter) RemoveAll(path string) error

RemoveAll removes path and any children it contains.

func (*AbsAdapter) Rename

func (a *AbsAdapter) Rename(oldpath, newpath string) error

Rename renames (moves) a file.

func (*AbsAdapter) SetContext

func (a *AbsAdapter) SetContext(ctx context.Context)

SetContext updates the context used for permission checking. This is useful when the identity needs to change during the adapter's lifetime.

func (*AbsAdapter) SetIdentity

func (a *AbsAdapter) SetIdentity(identity *Identity)

SetIdentity updates the identity used for permission checking. This creates a new context with the provided identity.

func (*AbsAdapter) Stat

func (a *AbsAdapter) Stat(name string) (os.FileInfo, error)

Stat returns file information.

func (*AbsAdapter) Sub

func (a *AbsAdapter) Sub(dir string) (fs.FS, error)

Sub returns a filesystem rooted at dir.

func (a *AbsAdapter) Symlink(oldname, newname string) error

Symlink creates newname as a symbolic link to oldname.

func (*AbsAdapter) TempDir

func (a *AbsAdapter) TempDir() string

TempDir returns the default directory for temporary files.

func (*AbsAdapter) Truncate

func (a *AbsAdapter) Truncate(name string, size int64) error

Truncate changes the size of the named file.

type AndCondition

type AndCondition struct {
	Conditions []Condition
}

AndCondition requires all sub-conditions to be true

func (*AndCondition) Evaluate

func (ac *AndCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate checks if all conditions are satisfied

func (*AndCondition) String

func (ac *AndCondition) String() string

String returns a string representation

type AuditConfig

type AuditConfig struct {
	// Enabled enables audit logging
	Enabled bool
	// Writer is where audit logs are written (defaults to os.Stdout)
	Writer io.Writer
	// Level controls what events are logged
	Level *AuditLevel
	// Async enables asynchronous logging
	Async bool
	// BufferSize is the size of the async buffer (default: 1000)
	BufferSize int
	// Handler is an optional custom event handler
	Handler AuditHandler
}

AuditConfig contains audit logging configuration (Phase 3)

type AuditEvent

type AuditEvent struct {
	// Timestamp is when the event occurred
	Timestamp time.Time `json:"timestamp"`
	// RequestID is a unique identifier for the request
	RequestID string `json:"request_id,omitempty"`
	// UserID is the user who attempted the operation
	UserID string `json:"user_id"`
	// Groups are the groups the user belongs to
	Groups []string `json:"groups,omitempty"`
	// Roles are the roles assigned to the user
	Roles []string `json:"roles,omitempty"`
	// Operation is the filesystem operation attempted
	Operation string `json:"operation"`
	// Path is the filesystem path accessed
	Path string `json:"path"`
	// Result is whether access was allowed or denied
	Result AuditResult `json:"result"`
	// Reason provides additional context for the result
	Reason string `json:"reason,omitempty"`
	// Duration is how long the permission check took
	Duration time.Duration `json:"duration_ms"`
	// Metadata contains additional context information
	Metadata map[string]interface{} `json:"metadata,omitempty"`
	// SourceIP is the IP address of the request (if available)
	SourceIP string `json:"source_ip,omitempty"`
}

AuditEvent represents a single audit log entry

type AuditHandler

type AuditHandler func(event *AuditEvent)

AuditHandler is a function that processes audit events

type AuditLevel

type AuditLevel int

AuditLevel defines the verbosity of audit logging

const (
	// AuditLevelNone disables audit logging
	AuditLevelNone AuditLevel = iota
	// AuditLevelDenied logs only denied access attempts
	AuditLevelDenied
	// AuditLevelAll logs all access attempts
	AuditLevelAll
)

type AuditLogger

type AuditLogger struct {
	// contains filtered or unexported fields
}

AuditLogger handles audit logging

func NewAuditLogger

func NewAuditLogger(config AuditConfig) *AuditLogger

NewAuditLogger creates a new audit logger

func (*AuditLogger) Close

func (al *AuditLogger) Close() error

Close shuts down the audit logger

func (*AuditLogger) GetMetrics

func (al *AuditLogger) GetMetrics() *AuditMetrics

GetMetrics returns audit metrics

func (*AuditLogger) Log

func (al *AuditLogger) Log(event *AuditEvent)

Log logs an audit event

type AuditMetrics

type AuditMetrics struct {
	// contains filtered or unexported fields
}

AuditMetrics tracks audit logging statistics

func NewAuditMetrics

func NewAuditMetrics() *AuditMetrics

NewAuditMetrics creates a new metrics tracker

func (*AuditMetrics) GetStats

func (am *AuditMetrics) GetStats() AuditStats

GetStats returns current metrics

func (*AuditMetrics) GetTopAccessedPaths

func (am *AuditMetrics) GetTopAccessedPaths(limit int) []PathAccessStat

GetTopAccessedPaths returns most accessed paths

func (*AuditMetrics) GetTopDeniedUsers

func (am *AuditMetrics) GetTopDeniedUsers(limit int) []UserDenialStat

GetTopDeniedUsers returns users with most denials

func (*AuditMetrics) IncrementDropped

func (am *AuditMetrics) IncrementDropped()

IncrementDropped increments the dropped events counter

func (*AuditMetrics) RecordEvent

func (am *AuditMetrics) RecordEvent(event *AuditEvent)

RecordEvent records metrics for an audit event

type AuditResult

type AuditResult string

AuditResult represents the result of an access attempt

const (
	// AuditResultAllowed indicates access was granted
	AuditResultAllowed AuditResult = "allowed"
	// AuditResultDenied indicates access was denied
	AuditResultDenied AuditResult = "denied"
	// AuditResultError indicates an error occurred
	AuditResultError AuditResult = "error"
)

type AuditStats

type AuditStats struct {
	TotalEvents     uint64
	AllowedEvents   uint64
	DeniedEvents    uint64
	ErrorEvents     uint64
	DroppedEvents   uint64
	AverageDuration time.Duration
}

AuditStats contains audit statistics

type Authenticator

type Authenticator interface {
	// Authenticate extracts and validates identity from the context
	Authenticate(ctx context.Context) (*Identity, error)
}

Authenticator is an interface for extracting identity from a context or token

type CacheEntry

type CacheEntry struct {
	Key       CacheKey
	Allowed   bool
	ExpiresAt time.Time
	// contains filtered or unexported fields
}

CacheEntry represents a cached permission evaluation result

func (*CacheEntry) IsExpired

func (ce *CacheEntry) IsExpired() bool

IsExpired checks if the cache entry has expired

type CacheKey

type CacheKey struct {
	UserID    string
	Path      string
	Operation Operation
}

CacheKey represents a cache key for permission evaluation

func (CacheKey) String

func (ck CacheKey) String() string

String returns a string representation of the cache key

type CacheStats

type CacheStats struct {
	Size      int
	MaxSize   int
	Hits      uint64
	Misses    uint64
	Evictions uint64
	HitRate   float64
}

CacheStats contains cache statistics

type ChainAuthenticator

type ChainAuthenticator struct {
	// contains filtered or unexported fields
}

ChainAuthenticator tries multiple authenticators in order

func NewChainAuthenticator

func NewChainAuthenticator(authenticators ...Authenticator) *ChainAuthenticator

NewChainAuthenticator creates a new chain authenticator

func (*ChainAuthenticator) Authenticate

func (ca *ChainAuthenticator) Authenticate(ctx context.Context) (*Identity, error)

Authenticate tries each authenticator in order

type Condition

type Condition interface {
	// Evaluate checks if the condition is satisfied
	Evaluate(ctx *EvaluationContext) bool
	// String returns a string representation of the condition
	String() string
}

Condition represents a conditional check that must pass for an ACL entry to apply

type Config

type Config struct {
	// ACL is the access control list
	ACL ACL
	// Audit configuration (placeholder for Phase 3)
	Audit AuditConfig
	// Performance configuration (placeholder for Phase 2)
	Performance PerformanceConfig
}

Config contains configuration for a permission filesystem

type CustomConditionFunc

type CustomConditionFunc func(ctx *EvaluationContext) bool

CustomConditionFunc is a function type for custom conditions

type Effect

type Effect int

Effect represents whether an ACL entry allows or denies access

const (
	// EffectDeny denies access (takes precedence)
	EffectDeny Effect = iota
	// EffectAllow allows access
	EffectAllow
)

func (Effect) String

func (e Effect) String() string

String returns a string representation of the effect

type EvaluationContext

type EvaluationContext struct {
	// Identity contains user, group, and role information
	Identity *Identity
	// Path is the filesystem path being accessed
	Path string
	// Operation is the operation being attempted
	Operation Operation
	// Metadata contains additional context information
	Metadata map[string]interface{}
}

EvaluationContext contains information needed to evaluate permissions

type Evaluator

type Evaluator struct {
	// contains filtered or unexported fields
}

Evaluator evaluates permissions based on ACL rules

func NewEvaluator

func NewEvaluator(acl ACL) *Evaluator

NewEvaluator creates a new permission evaluator

func NewEvaluatorWithCache

func NewEvaluatorWithCache(acl ACL, cache *PermissionCache, patternCache *PatternCache) *Evaluator

NewEvaluatorWithCache creates a new evaluator with caching enabled

func (*Evaluator) CanAccessMetadata

func (e *Evaluator) CanAccessMetadata(identity *Identity, path string) bool

CanAccessMetadata checks if the identity can access metadata for the path

func (*Evaluator) CanDelete

func (e *Evaluator) CanDelete(identity *Identity, path string) bool

CanDelete checks if the identity can delete the path

func (*Evaluator) CanExecute

func (e *Evaluator) CanExecute(identity *Identity, path string) bool

CanExecute checks if the identity can execute the path

func (*Evaluator) CanRead

func (e *Evaluator) CanRead(identity *Identity, path string) bool

CanRead checks if the identity can read the path

func (*Evaluator) CanWrite

func (e *Evaluator) CanWrite(identity *Identity, path string) bool

CanWrite checks if the identity can write to the path

func (*Evaluator) ClearCache

func (e *Evaluator) ClearCache()

ClearCache clears the permission cache

func (*Evaluator) Evaluate

func (e *Evaluator) Evaluate(ctx *EvaluationContext) (bool, error)

Evaluate checks if the given operation is allowed for the context

func (*Evaluator) GetCacheStats

func (e *Evaluator) GetCacheStats() *CacheStats

GetCacheStats returns cache statistics

func (*Evaluator) GetEffectivePermissions

func (e *Evaluator) GetEffectivePermissions(identity *Identity, path string) Operation

GetEffectivePermissions returns the effective permissions for a path and identity

func (*Evaluator) GetMatchingEntries

func (e *Evaluator) GetMatchingEntries(ctx *EvaluationContext) []ACLEntry

GetMatchingEntries returns all ACL entries that match the given context

func (*Evaluator) InvalidateCache

func (e *Evaluator) InvalidateCache(userID string, pathPrefix string)

InvalidateCache invalidates cache entries for a user and/or path prefix

func (*Evaluator) IsAdmin

func (e *Evaluator) IsAdmin(identity *Identity, path string) bool

IsAdmin checks if the identity has admin permissions for the path

type File

type File interface {
	fs.File
	// Write writes data to the file
	Write(p []byte) (n int, err error)
	// WriteAt writes data at the specified offset
	WriteAt(p []byte, off int64) (n int, err error)
	// Read reads data from the file
	Read(p []byte) (n int, err error)
	// ReadAt reads data from the specified offset
	ReadAt(p []byte, off int64) (n int, err error)
	// Seek sets the offset for the next Read or Write
	Seek(offset int64, whence int) (int64, error)
	// Sync commits the current contents of the file
	Sync() error
	// Truncate changes the size of the file
	Truncate(size int64) error
}

File is the interface for file operations

type FileSystem

type FileSystem interface {
	// OpenFile opens a file with the specified flag and perm
	OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (File, error)

	// Mkdir creates a directory
	Mkdir(ctx context.Context, name string, perm os.FileMode) error

	// MkdirAll creates a directory and all parent directories
	MkdirAll(ctx context.Context, name string, perm os.FileMode) error

	// Remove removes a file or directory
	Remove(ctx context.Context, name string) error

	// RemoveAll removes a path and any children it contains
	RemoveAll(ctx context.Context, name string) error

	// Rename renames (moves) a file
	Rename(ctx context.Context, oldname, newname string) error

	// Stat returns file info
	Stat(ctx context.Context, name string) (os.FileInfo, error)

	// Lstat returns file info without following symlinks
	Lstat(ctx context.Context, name string) (os.FileInfo, error)

	// ReadDir reads the directory and returns file info
	ReadDir(ctx context.Context, name string) ([]os.FileInfo, error)

	// Chmod changes the mode of the file
	Chmod(ctx context.Context, name string, mode os.FileMode) error

	// Chown changes the owner and group of the file
	Chown(ctx context.Context, name string, uid, gid int) error

	// Chtimes changes the access and modification times
	Chtimes(ctx context.Context, name string, atime, mtime time.Time) error
}

FileSystem is the interface that permfs wraps This matches the absfs.FileSystem interface

type FuncAuthenticator

type FuncAuthenticator func(ctx context.Context) (*Identity, error)

FuncAuthenticator wraps a function as an Authenticator

func (FuncAuthenticator) Authenticate

func (fa FuncAuthenticator) Authenticate(ctx context.Context) (*Identity, error)

Authenticate calls the wrapped function

type FuncCondition

type FuncCondition struct {
	Name string
	Func CustomConditionFunc
}

FuncCondition wraps a function as a Condition

func NewFuncCondition

func NewFuncCondition(name string, fn CustomConditionFunc) *FuncCondition

NewFuncCondition creates a new function-based condition

func (*FuncCondition) Evaluate

func (fc *FuncCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate executes the custom function

func (*FuncCondition) String

func (fc *FuncCondition) String() string

String returns a string representation

type HeaderAuthenticator

type HeaderAuthenticator struct {
	// contains filtered or unexported fields
}

HeaderAuthenticator extracts identity from HTTP-style headers in metadata

func NewHeaderAuthenticator

func NewHeaderAuthenticator(userHeader, groupsHeader, rolesHeader string) *HeaderAuthenticator

NewHeaderAuthenticator creates a new header authenticator

func (*HeaderAuthenticator) Authenticate

func (ha *HeaderAuthenticator) Authenticate(ctx context.Context) (*Identity, error)

Authenticate extracts identity from headers in metadata

type HourRange

type HourRange struct {
	Start int // 0-23
	End   int // 0-23
}

HourRange represents a range of hours

type IPCondition

type IPCondition struct {
	// AllowedNetworks contains allowed CIDR ranges
	AllowedNetworks []*net.IPNet
	// DeniedNetworks contains explicitly denied CIDR ranges (takes precedence)
	DeniedNetworks []*net.IPNet
}

IPCondition checks if the request comes from an allowed IP address or network

func NewIPCondition

func NewIPCondition(allowedCIDRs, deniedCIDRs []string) (*IPCondition, error)

NewIPCondition creates a new IP condition from CIDR strings

func (*IPCondition) Evaluate

func (ic *IPCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate checks if the source IP satisfies the condition

func (*IPCondition) String

func (ic *IPCondition) String() string

String returns a string representation

type Identity

type Identity struct {
	// UserID is the unique identifier for the user
	UserID string
	// Groups is a list of groups the user belongs to
	Groups []string
	// Roles is a list of roles assigned to the user
	Roles []string
	// Metadata contains additional identity information
	Metadata map[string]string
}

Identity represents a user's identity and group memberships

func GetIdentity

func GetIdentity(ctx context.Context) (*Identity, error)

GetIdentity extracts the identity from the context

func (*Identity) HasGroup

func (i *Identity) HasGroup(group string) bool

HasGroup checks if the identity belongs to the given group

func (*Identity) HasRole

func (i *Identity) HasRole(role string) bool

HasRole checks if the identity has the given role

func (*Identity) Matches

func (i *Identity) Matches(subject Subject) bool

Matches checks if the identity matches the given subject

type MetadataCondition

type MetadataCondition struct {
	// Key is the metadata key to check
	Key string
	// Values are allowed values (any match allows access)
	Values []string
	// CaseSensitive determines if value comparison is case sensitive
	CaseSensitive bool
}

MetadataCondition checks metadata key-value pairs

func (*MetadataCondition) Evaluate

func (mc *MetadataCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate checks if metadata satisfies the condition

func (*MetadataCondition) String

func (mc *MetadataCondition) String() string

String returns a string representation

type NotCondition

type NotCondition struct {
	Condition Condition
}

NotCondition inverts a condition

func (*NotCondition) Evaluate

func (nc *NotCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate inverts the result of the wrapped condition

func (*NotCondition) String

func (nc *NotCondition) String() string

String returns a string representation

type Operation

type Operation uint32

Operation represents a filesystem operation type

const (
	// OperationRead allows opening files for reading and listing directories
	OperationRead Operation = 1 << iota
	// OperationWrite allows creating, modifying, or appending to files
	OperationWrite
	// OperationExecute allows executing files
	OperationExecute
	// OperationDelete allows removing files or directories
	OperationDelete
	// OperationMetadata allows reading/modifying file attributes, permissions, timestamps
	OperationMetadata
	// OperationAdmin allows full control including permission changes
	OperationAdmin

	// OperationAll grants all permissions
	OperationAll Operation = OperationRead | OperationWrite | OperationExecute | OperationDelete | OperationMetadata | OperationAdmin
)

func (Operation) Has

func (o Operation) Has(op Operation) bool

Has checks if the operation set includes the given operation

func (Operation) String

func (o Operation) String() string

String returns a string representation of the operation

type OperationSet

type OperationSet = Operation

OperationSet is an alias for Operation (for backwards compatibility with API examples)

type OrCondition

type OrCondition struct {
	Conditions []Condition
}

OrCondition requires at least one sub-condition to be true

func (*OrCondition) Evaluate

func (oc *OrCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate checks if any condition is satisfied

func (*OrCondition) String

func (oc *OrCondition) String() string

String returns a string representation

type PathAccessStat

type PathAccessStat struct {
	Path  string
	Count uint64
}

PathAccessStat tracks access count for a path

type PatternCache

type PatternCache struct {
	// contains filtered or unexported fields
}

PatternCache caches compiled path patterns

func NewPatternCache

func NewPatternCache() *PatternCache

NewPatternCache creates a new pattern cache

func (*PatternCache) Clear

func (pc *PatternCache) Clear()

Clear removes all cached patterns

func (*PatternCache) Get

func (pc *PatternCache) Get(pattern string) (*PatternMatcher, bool)

Get retrieves a cached pattern matcher

func (*PatternCache) GetOrCreate

func (pc *PatternCache) GetOrCreate(pattern string) (*PatternMatcher, error)

GetOrCreate gets a cached pattern or creates a new one

func (*PatternCache) Set

func (pc *PatternCache) Set(pattern string, matcher *PatternMatcher)

Set stores a pattern matcher in the cache

func (*PatternCache) Size

func (pc *PatternCache) Size() int

Size returns the number of cached patterns

type PatternMatcher

type PatternMatcher struct {
	// contains filtered or unexported fields
}

PatternMatcher provides compiled pattern matching

func NewPatternMatcher

func NewPatternMatcher(pattern string) (*PatternMatcher, error)

NewPatternMatcher creates a new pattern matcher

func (*PatternMatcher) Match

func (pm *PatternMatcher) Match(pathStr string) (bool, error)

Match checks if a path matches the pattern

func (*PatternMatcher) Pattern

func (pm *PatternMatcher) Pattern() string

Pattern returns the original pattern string

type PerformanceConfig

type PerformanceConfig struct {
	// CacheEnabled enables permission result caching
	CacheEnabled bool
	// CacheTTL is the time-to-live for cache entries
	CacheTTL time.Duration
	// CacheMaxSize is the maximum number of entries in the cache
	CacheMaxSize int
	// PatternCacheEnabled enables pattern compilation caching
	PatternCacheEnabled bool
}

PerformanceConfig contains performance optimization settings (Phase 2)

type PermFS

type PermFS struct {
	// contains filtered or unexported fields
}

PermFS wraps a FileSystem with permission checking

func New

func New(base FileSystem, config Config) (*PermFS, error)

New creates a new permission filesystem

func NewPermFSWithAuthenticator

func NewPermFSWithAuthenticator(base FileSystem, config Config, auth Authenticator) (*PermFS, error)

NewPermFSWithAuthenticator creates a new PermFS with an authenticator

func (*PermFS) AddRule

func (pfs *PermFS) AddRule(entry ACLEntry) error

AddRule adds a new ACL entry (for dynamic rule management)

func (*PermFS) Chmod

func (pfs *PermFS) Chmod(ctx context.Context, name string, mode os.FileMode) error

Chmod changes file mode with permission checking

func (*PermFS) Chown

func (pfs *PermFS) Chown(ctx context.Context, name string, uid, gid int) error

Chown changes file ownership with permission checking

func (*PermFS) Chtimes

func (pfs *PermFS) Chtimes(ctx context.Context, name string, atime, mtime time.Time) error

Chtimes changes file access and modification times with permission checking

func (*PermFS) ClearCache

func (pfs *PermFS) ClearCache()

ClearCache clears the permission cache

func (*PermFS) Close

func (pfs *PermFS) Close() error

Close closes the permission filesystem and shuts down background tasks

func (*PermFS) GetAuditMetrics

func (pfs *PermFS) GetAuditMetrics() *AuditMetrics

GetAuditMetrics returns the audit metrics object

func (*PermFS) GetAuditStats

func (pfs *PermFS) GetAuditStats() AuditStats

GetAuditStats returns audit statistics

func (*PermFS) GetCacheStats

func (pfs *PermFS) GetCacheStats() *CacheStats

GetCacheStats returns cache statistics

func (*PermFS) GetEffectiveRules

func (pfs *PermFS) GetEffectiveRules(path string) []ACLEntry

GetEffectiveRules returns all ACL entries that apply to a path

func (*PermFS) GetPermissions

func (pfs *PermFS) GetPermissions(ctx context.Context, path string) (Operation, error)

GetPermissions returns the effective permissions for a path and identity

func (*PermFS) InvalidateCache

func (pfs *PermFS) InvalidateCache(userID string, pathPrefix string)

InvalidateCache invalidates cache entries for a user and/or path prefix

func (*PermFS) Lstat

func (pfs *PermFS) Lstat(ctx context.Context, name string) (os.FileInfo, error)

Lstat returns file info without following symlinks, with permission checking

func (*PermFS) Mkdir

func (pfs *PermFS) Mkdir(ctx context.Context, name string, perm os.FileMode) error

Mkdir creates a directory with permission checking

func (*PermFS) MkdirAll

func (pfs *PermFS) MkdirAll(ctx context.Context, name string, perm os.FileMode) error

MkdirAll creates a directory and all parents with permission checking

func (*PermFS) OpenFile

func (pfs *PermFS) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (File, error)

OpenFile opens a file with permission checking

func (*PermFS) ReadDir

func (pfs *PermFS) ReadDir(ctx context.Context, name string) ([]os.FileInfo, error)

ReadDir reads a directory with permission checking (context-based, returns []os.FileInfo) This method implements the internal FileSystem interface

func (*PermFS) Remove

func (pfs *PermFS) Remove(ctx context.Context, name string) error

Remove removes a file or directory with permission checking

func (*PermFS) RemoveAll

func (pfs *PermFS) RemoveAll(ctx context.Context, name string) error

RemoveAll removes a path recursively with permission checking

func (*PermFS) RemoveRule

func (pfs *PermFS) RemoveRule(entry ACLEntry) error

RemoveRule removes an ACL entry by matching all fields

func (*PermFS) Rename

func (pfs *PermFS) Rename(ctx context.Context, oldname, newname string) error

Rename renames a file with permission checking

func (*PermFS) Stat

func (pfs *PermFS) Stat(ctx context.Context, name string) (os.FileInfo, error)

Stat returns file info with permission checking

func (*PermFS) TestPermission

func (pfs *PermFS) TestPermission(identity *Identity, path string, op Operation) (bool, *PermissionTestResult)

TestPermission simulates a permission check without actually performing it

type PermissionCache

type PermissionCache struct {
	// contains filtered or unexported fields
}

PermissionCache provides LRU caching for permission evaluations

func NewPermissionCache

func NewPermissionCache(maxSize int, ttl time.Duration) *PermissionCache

NewPermissionCache creates a new permission cache

func (*PermissionCache) Clear

func (pc *PermissionCache) Clear()

Clear removes all entries from the cache

func (*PermissionCache) Disable

func (pc *PermissionCache) Disable()

Disable disables the cache

func (*PermissionCache) Enable

func (pc *PermissionCache) Enable()

Enable enables the cache

func (*PermissionCache) Get

func (pc *PermissionCache) Get(key CacheKey) (allowed bool, found bool)

Get retrieves a cached permission result

func (*PermissionCache) Invalidate

func (pc *PermissionCache) Invalidate(userID string, pathPrefix string)

Invalidate removes entries matching a pattern

func (*PermissionCache) IsEnabled

func (pc *PermissionCache) IsEnabled() bool

IsEnabled returns whether the cache is enabled

func (*PermissionCache) Set

func (pc *PermissionCache) Set(key CacheKey, allowed bool)

Set stores a permission result in the cache

func (*PermissionCache) Stats

func (pc *PermissionCache) Stats() CacheStats

Stats returns cache statistics

type PermissionError

type PermissionError struct {
	// Path is the filesystem path that was denied
	Path string
	// Operation is the operation that was denied
	Operation Operation
	// UserID is the user who was denied
	UserID string
	// Reason provides additional context for the denial
	Reason string
}

PermissionError represents a permission denial with additional context

func (*PermissionError) Error

func (e *PermissionError) Error() string

Error implements the error interface

func (*PermissionError) Unwrap

func (e *PermissionError) Unwrap() error

Unwrap returns the underlying error

type PermissionTestResult

type PermissionTestResult struct {
	Allowed         bool
	MatchingEntries []ACLEntry
	Path            string
	Operation       Operation
	Identity        *Identity
}

PermissionTestResult contains the result of a permission test

func (*PermissionTestResult) Explain

func (ptr *PermissionTestResult) Explain() string

Explain returns a human-readable explanation of the permission decision

type PolicyEntryExport

type PolicyEntryExport struct {
	Subject     SubjectExport `json:"subject" yaml:"subject"`
	PathPattern string        `json:"path_pattern" yaml:"path_pattern"`
	Permissions []string      `json:"permissions" yaml:"permissions"`
	Effect      string        `json:"effect" yaml:"effect"`
	Priority    int           `json:"priority" yaml:"priority"`
}

PolicyEntryExport represents a serializable ACL entry

type PolicyFile

type PolicyFile struct {
	Version     string              `json:"version" yaml:"version"`
	Description string              `json:"description,omitempty" yaml:"description,omitempty"`
	Default     string              `json:"default" yaml:"default"`
	Entries     []PolicyEntryExport `json:"entries" yaml:"entries"`
}

PolicyFile represents a serializable policy

func ExportPolicy

func ExportPolicy(acl ACL, description string) *PolicyFile

ExportPolicy exports an ACL to a policy file format

func LoadPolicy

func LoadPolicy(r io.Reader, format PolicyFormat) (*PolicyFile, error)

LoadPolicy loads a policy from a reader

func LoadPolicyFromFile

func LoadPolicyFromFile(filename string, format PolicyFormat) (*PolicyFile, error)

LoadPolicyFromFile loads a policy from a file

type PolicyFormat

type PolicyFormat int

PolicyFormat represents the format of a policy file

const (
	// PolicyFormatJSON represents JSON format
	PolicyFormatJSON PolicyFormat = iota
	// PolicyFormatYAML represents YAML format
	PolicyFormatYAML
)

type RuleConflict

type RuleConflict struct {
	Rule1       ACLEntry
	Rule2       ACLEntry
	Description string
}

RuleConflict represents a potential conflict between two rules

func FindConflictingRules

func FindConflictingRules(acl ACL) []RuleConflict

FindConflictingRules finds rules that might conflict with each other

type StaticAuthenticator

type StaticAuthenticator struct {
	// contains filtered or unexported fields
}

StaticAuthenticator provides a simple static user mapping

func NewStaticAuthenticator

func NewStaticAuthenticator() *StaticAuthenticator

NewStaticAuthenticator creates a new static authenticator

func (*StaticAuthenticator) AddUser

func (sa *StaticAuthenticator) AddUser(userID string, groups, roles []string)

AddUser adds a user to the static authenticator

func (*StaticAuthenticator) Authenticate

func (sa *StaticAuthenticator) Authenticate(ctx context.Context) (*Identity, error)

Authenticate extracts identity from context

func (*StaticAuthenticator) AuthenticateToken

func (sa *StaticAuthenticator) AuthenticateToken(token string) (*Identity, error)

AuthenticateToken authenticates a token (simple user ID lookup)

type Subject

type Subject struct {
	Type SubjectType
	ID   string
}

Subject represents who an ACL entry applies to

func Everyone

func Everyone() Subject

Everyone creates a Subject representing all users

func Group

func Group(id string) Subject

Group creates a Subject representing a group

func Role

func Role(id string) Subject

Role creates a Subject representing a role

func User

func User(id string) Subject

User creates a Subject representing a specific user

func (Subject) String

func (s Subject) String() string

String returns a string representation of the subject

type SubjectExport

type SubjectExport struct {
	Type string `json:"type" yaml:"type"`
	ID   string `json:"id" yaml:"id"`
}

SubjectExport represents a serializable subject

type SubjectType

type SubjectType int

SubjectType represents the type of subject in an ACL entry

const (
	// SubjectTypeUser represents a specific user
	SubjectTypeUser SubjectType = iota
	// SubjectTypeGroup represents a group of users
	SubjectTypeGroup
	// SubjectTypeRole represents a role
	SubjectTypeRole
	// SubjectTypeEveryone represents all users (wildcard)
	SubjectTypeEveryone
)

func (SubjectType) String

func (st SubjectType) String() string

String returns a string representation of the subject type

type TimeCondition

type TimeCondition struct {
	// AllowedHours contains allowed hour ranges (0-23)
	AllowedHours []HourRange
	// AllowedDays contains allowed days of week (0=Sunday, 6=Saturday)
	AllowedDays []time.Weekday
	// Timezone for time evaluation (nil uses UTC)
	Timezone *time.Location
}

TimeCondition checks if the current time falls within allowed time ranges

func NewBusinessHoursCondition

func NewBusinessHoursCondition() *TimeCondition

NewBusinessHoursCondition creates a condition for standard business hours (9am-5pm, weekdays)

func (*TimeCondition) Evaluate

func (tc *TimeCondition) Evaluate(ctx *EvaluationContext) bool

Evaluate checks if the current time satisfies the condition

func (*TimeCondition) String

func (tc *TimeCondition) String() string

String returns a string representation

type TokenAuthenticator

type TokenAuthenticator interface {
	// AuthenticateToken validates a token and returns the identity
	AuthenticateToken(token string) (*Identity, error)
}

TokenAuthenticator extracts identity from a token string

type UserDenialStat

type UserDenialStat struct {
	UserID string
	Count  uint64
}

UserDenialStat tracks denial count for a user

type ValidationError

type ValidationError struct {
	Field   string
	Message string
}

ValidationError represents a validation error

func (*ValidationError) Error

func (ve *ValidationError) Error() string

Error implements the error interface

type ValidationResult

type ValidationResult struct {
	Valid  bool
	Errors []ValidationError
}

ValidationResult contains the result of validation

func ValidateACL

func ValidateACL(acl ACL) ValidationResult

ValidateACL validates an ACL configuration

func ValidateACLEntry

func ValidateACLEntry(entry ACLEntry) ValidationResult

ValidateACLEntry validates a single ACL entry

func (*ValidationResult) AddError

func (vr *ValidationResult) AddError(field, message string)

AddError adds an error to the validation result

Directories

Path Synopsis
examples
basic command
comprehensive command
multi_tenant command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL