88 lines
3.3 KiB
Go
88 lines
3.3 KiB
Go
package agentguard
|
|
|
|
import "fmt"
|
|
|
|
// BlockerCode is a stable machine-readable admission failure category.
|
|
type BlockerCode string
|
|
|
|
const (
|
|
BlockerCodeUnknown BlockerCode = "unknown"
|
|
BlockerCodeMissingWorkspaceGrant BlockerCode = "missing_workspace_grant"
|
|
BlockerCodeInvalidAdmissionRequest BlockerCode = "invalid_admission_request"
|
|
BlockerCodeWorkspaceNotCanonical BlockerCode = "workspace_not_canonical"
|
|
BlockerCodeWorkspaceRootEscape BlockerCode = "workspace_root_escape"
|
|
BlockerCodeVCSMetadataNotAllowed BlockerCode = "vcs_metadata_not_allowed"
|
|
BlockerCodeIsolationRequired BlockerCode = "isolation_required"
|
|
BlockerCodeWritableRootEscape BlockerCode = "writable_root_escape"
|
|
BlockerCodeWritableConfinementUnavailable BlockerCode = "writable_root_confinement_unavailable"
|
|
BlockerCodeProviderUnattendedUnavailable BlockerCode = "provider_unattended_unavailable"
|
|
BlockerCodeProviderApprovalBypassUnavailable BlockerCode = "provider_approval_bypass_unavailable"
|
|
BlockerCodeRevisionMismatch BlockerCode = "revision_mismatch"
|
|
BlockerCodePermitInvalid BlockerCode = "permit_invalid"
|
|
BlockerCodePermitStale BlockerCode = "permit_stale"
|
|
BlockerCodeWorkspaceIdentityMismatch BlockerCode = "workspace_identity_mismatch"
|
|
)
|
|
|
|
var knownBlockerCodes = map[BlockerCode]struct{}{
|
|
BlockerCodeUnknown: {},
|
|
BlockerCodeMissingWorkspaceGrant: {},
|
|
BlockerCodeInvalidAdmissionRequest: {},
|
|
BlockerCodeWorkspaceNotCanonical: {},
|
|
BlockerCodeWorkspaceRootEscape: {},
|
|
BlockerCodeVCSMetadataNotAllowed: {},
|
|
BlockerCodeIsolationRequired: {},
|
|
BlockerCodeWritableRootEscape: {},
|
|
BlockerCodeWritableConfinementUnavailable: {},
|
|
BlockerCodeProviderUnattendedUnavailable: {},
|
|
BlockerCodeProviderApprovalBypassUnavailable: {},
|
|
BlockerCodeRevisionMismatch: {},
|
|
BlockerCodePermitInvalid: {},
|
|
BlockerCodePermitStale: {},
|
|
BlockerCodeWorkspaceIdentityMismatch: {},
|
|
}
|
|
|
|
// NormalizeBlockerCode keeps future codes from being treated as a known local
|
|
// policy decision.
|
|
func NormalizeBlockerCode(code BlockerCode) BlockerCode {
|
|
if _, ok := knownBlockerCodes[code]; ok {
|
|
return code
|
|
}
|
|
return BlockerCodeUnknown
|
|
}
|
|
|
|
// Blocker is safe for task-local persistence. It carries stable identities,
|
|
// never raw paths or provider diagnostics.
|
|
type Blocker struct {
|
|
Code BlockerCode
|
|
Message string
|
|
ProjectID string
|
|
ProviderID string
|
|
ProfileID string
|
|
}
|
|
|
|
func (b *Blocker) Error() string {
|
|
if b == nil {
|
|
return ""
|
|
}
|
|
if b.Message != "" {
|
|
return b.Message
|
|
}
|
|
return fmt.Sprintf("agent admission blocked: %s", b.Code)
|
|
}
|
|
|
|
func blockedResult(req AdmissionRequest, code BlockerCode, message string) AdmissionResult {
|
|
blocker := &Blocker{
|
|
Code: NormalizeBlockerCode(code),
|
|
Message: message,
|
|
ProviderID: req.Profile.ProviderID,
|
|
ProfileID: req.Profile.ProfileID,
|
|
}
|
|
if req.Grant != nil {
|
|
blocker.ProjectID = req.Grant.ProjectID
|
|
}
|
|
return AdmissionResult{
|
|
Status: AdmissionStatusBlocked,
|
|
Blocker: blocker,
|
|
Notification: notificationFor(blocker),
|
|
}
|
|
}
|