package agentguard import ( "fmt" "os" "path/filepath" "sort" "strings" ) type canonicalPath struct { path string info os.FileInfo } type evaluatedAdmission struct { workspace CanonicalWorkspace payload permitPayload pins []canonicalPath } func evaluateAdmission(req AdmissionRequest) (evaluatedAdmission, AdmissionResult) { if result := validateAdmissionInputs(req); result.Blocker != nil { return evaluatedAdmission{}, result } grantRoot, err := canonicalDirectory(req.Grant.Root, true) if err != nil { return evaluatedAdmission{}, blockedResult( req, BlockerCodeWorkspaceNotCanonical, "registered workspace root is not an existing canonical directory", ) } baseRoot, err := canonicalDirectory(req.Isolation.BaseRoot, true) if err != nil || baseRoot.path != grantRoot.path { return evaluatedAdmission{}, blockedResult( req, BlockerCodeRevisionMismatch, "task isolation base does not match the registered workspace revision", ) } taskRoot, err := canonicalDirectory(req.Isolation.TaskRoot, true) if err != nil { return evaluatedAdmission{}, blockedResult( req, BlockerCodeWorkspaceNotCanonical, "task isolation root is not an existing canonical directory", ) } if taskRoot.path == grantRoot.path { return evaluatedAdmission{}, blockedResult( req, BlockerCodeIsolationRequired, "task execution cannot write directly to the canonical workspace", ) } workingInput := req.Isolation.WorkingDir if strings.TrimSpace(workingInput) == "" { workingInput = taskRoot.path } workingDir, err := canonicalDirectory(workingInput, false) if err != nil || !containsPath(taskRoot.path, workingDir.path) { return evaluatedAdmission{}, blockedResult( req, BlockerCodeWorkspaceRootEscape, "task working directory resolves outside the isolated workspace", ) } writableRoots := make([]canonicalPath, 0, len(req.Isolation.WritableRoots)) for _, root := range req.Isolation.WritableRoots { canonical, canonicalErr := canonicalDirectory(root, false) if canonicalErr != nil || !containsPath(taskRoot.path, canonical.path) { return evaluatedAdmission{}, blockedResult( req, BlockerCodeWritableRootEscape, "one or more writable roots resolve outside the isolated workspace", ) } writableRoots = append(writableRoots, canonical) } allowedVCS, allowedPins, err := canonicalVCSAllowances(req.Grant.VCSMetadataRoots) if err != nil { return evaluatedAdmission{}, blockedResult( req, BlockerCodeWorkspaceNotCanonical, "workspace grant contains an invalid VCS metadata allowance", ) } rootVCS, gitErr := discoverGitMetadata(taskRoot.path, req.Isolation.Mode) if gitErr != nil { return evaluatedAdmission{}, blockedResult(req, gitErr.code, gitErr.message) } effectiveVCS, gitErr := discoverEffectiveGitMetadata(taskRoot.path, workingDir.path) if gitErr != nil { return evaluatedAdmission{}, blockedResult(req, gitErr.code, gitErr.message) } actualVCS := deduplicatePins(append(rootVCS, effectiveVCS...)) for _, metadata := range actualVCS { if containsPath(taskRoot.path, metadata.path) { continue } if _, ok := allowedVCS[metadata.path]; !ok { return evaluatedAdmission{}, blockedResult( req, BlockerCodeVCSMetadataNotAllowed, "task Git metadata resolves outside the isolation without an exact grant allowance", ) } } writablePaths := canonicalPathStrings(writableRoots) vcsPaths := canonicalPathStrings(actualVCS) sort.Strings(writablePaths) sort.Strings(vcsPaths) workspace := CanonicalWorkspace{ ProjectID: req.Grant.ProjectID, WorkspaceID: req.Grant.WorkspaceID, GrantRevision: req.Grant.Revision, IsolationID: req.Isolation.ID, IsolationRevision: req.Isolation.Revision, PinnedBaseRevision: req.Isolation.PinnedBaseRevision, ConfinementRevision: req.Isolation.ConfinementRevision, Mode: req.Isolation.Mode, BaseRoot: grantRoot.path, TaskRoot: taskRoot.path, WorkingDir: workingDir.path, WritableRoots: writablePaths, VCSMetadataRoots: vcsPaths, } payload := permitPayload{ Workspace: workspace, Profile: req.Profile, } pins := deduplicatePins(append( []canonicalPath{grantRoot, baseRoot, taskRoot, workingDir}, append(writableRoots, append(allowedPins, actualVCS...)...)..., )) return evaluatedAdmission{ workspace: workspace, payload: payload, pins: pins, }, AdmissionResult{} } func validateAdmissionInputs(req AdmissionRequest) AdmissionResult { if req.Grant == nil { return blockedResult( req, BlockerCodeMissingWorkspaceGrant, "workspace is not backed by a registered canonical grant", ) } if req.Isolation == nil { return blockedResult( req, BlockerCodeIsolationRequired, "task execution requires an isolated writable workspace", ) } if req.Profile.ProviderID == "" || req.Profile.ModelID == "" || req.Profile.ProfileID == "" || req.Profile.Revision == "" || req.Grant.ProjectID == "" || req.Grant.WorkspaceID == "" || req.Grant.Revision == "" || req.Isolation.ID == "" || req.Isolation.Revision == "" || req.Isolation.PinnedBaseRevision == "" { return blockedResult( req, BlockerCodeInvalidAdmissionRequest, "admission identities and immutable revisions must be complete", ) } switch req.Isolation.Mode { case IsolationModeOverlay, IsolationModeWorktree, IsolationModeClone: default: return blockedResult( req, BlockerCodeInvalidAdmissionRequest, "task isolation mode is unsupported", ) } if !req.Profile.Unattended { return blockedResult( req, BlockerCodeProviderUnattendedUnavailable, "provider profile does not support unattended execution", ) } if !req.Profile.ApprovalBypass { return blockedResult( req, BlockerCodeProviderApprovalBypassUnavailable, "provider profile does not support approval bypass", ) } if !req.Profile.WritableRootConfinement || req.Isolation.ConfinementRevision == "" { return blockedResult( req, BlockerCodeWritableConfinementUnavailable, "provider profile cannot consume executable writable-root confinement", ) } if len(req.Isolation.WritableRoots) == 0 { return blockedResult( req, BlockerCodeWritableConfinementUnavailable, "task isolation declares no writable root", ) } return AdmissionResult{} } func canonicalDirectory(raw string, requireCanonical bool) (canonicalPath, error) { if strings.TrimSpace(raw) == "" || strings.TrimSpace(raw) != raw || !filepath.IsAbs(raw) || containsParentReference(raw) { return canonicalPath{}, fmt.Errorf("path must be absolute and clean") } cleaned := filepath.Clean(raw) resolved, err := filepath.EvalSymlinks(cleaned) if err != nil { return canonicalPath{}, err } resolved = filepath.Clean(resolved) if requireCanonical && resolved != cleaned { return canonicalPath{}, fmt.Errorf("path is not canonical") } info, err := os.Stat(resolved) if err != nil { return canonicalPath{}, err } if !info.IsDir() { return canonicalPath{}, fmt.Errorf("path is not a directory") } handle, err := os.Open(resolved) if err != nil { return canonicalPath{}, err } _ = handle.Close() return canonicalPath{path: resolved, info: info}, nil } func canonicalVCSAllowances(paths []string) (map[string]struct{}, []canonicalPath, error) { allowed := make(map[string]struct{}, len(paths)) pins := make([]canonicalPath, 0, len(paths)) for _, path := range paths { canonical, err := canonicalDirectory(path, true) if err != nil { return nil, nil, err } allowed[canonical.path] = struct{}{} pins = append(pins, canonical) } return allowed, pins, nil } func canonicalPathStrings(paths []canonicalPath) []string { result := make([]string, 0, len(paths)) for _, path := range paths { result = append(result, path.path) } return result } func deduplicatePins(paths []canonicalPath) []canonicalPath { seen := make(map[string]struct{}, len(paths)) result := make([]canonicalPath, 0, len(paths)) for _, path := range paths { if _, ok := seen[path.path]; ok { continue } seen[path.path] = struct{}{} result = append(result, path) } sort.Slice(result, func(i, j int) bool { return result[i].path < result[j].path }) return result }