-
Notifications
You must be signed in to change notification settings - Fork 0
Security Model
UEBPCracker implements a layered security model designed for local-development use. The MCP endpoint runs exclusively on localhost and all operations are gated by policy layers that default to the most restrictive settings.
| Level | Name | Operations | Enabled By |
|---|---|---|---|
| L0 | Read | inspect, snapshot, capabilities, health_check, check_completion, get_domain_capabilities | Always allowed (read-only, no INI needed) |
| L1 | Create | create_blueprint, add_variable, add_component, add_function_graph, add_node, set_pin_default, connect_pins, apply_blueprint_spec |
bEnableWriteOperations=True in INI |
| L2 | Patch | plan_blueprint_patch, apply_blueprint_patch | L1 + bRequirePlanHashForPatch=True (sealed hash) |
| L3 | Destructive | restore_operation_backup, discard_operation_backup |
bEnableDestructiveOperations=True in INI |
All settings live in Config/DefaultUEBPCracker.ini inside the plugin or host project:
[/Script/UEBPCrackerEditor.UEBPCrackerSettings]
; Write gate (default: False)
bEnableWriteOperations=True
; Destructive ops gate (default: False — even for testing)
bEnableDestructiveOperations=False
; Require sealed plan hash for patch operations (default: True)
bRequirePlanHashForPatch=True
; Require durable backup before destructive ops (default: True)
bRequireBackupForDestructive=True
; Loopback-only bind (default: True — do NOT set False for production)
bAllowRemoteMCPBind=False
; Allowed write roots (one per line)
AllowedWriteRoots=/Game/AI/
; Spec root directory (relative to project)
SpecRootDirectory=BlueprintSpecs
; Backup root (must be within a write root)
BackupRoot=/Game/AI/__UEBPCrackerBackups
; State/journal roots
StateRoot=/Game/AI/__UEBPCrackerState
JournalRoot=/Game/AI/__UEBPCrackerJournalThe host project's INI takes precedence over the plugin's default INI (standard UDeveloperSettings override chain).
All content paths are validated by FUEBPPathPolicy before any operation:
-
Absolute path rejection — paths starting with drive letters or
/outside/Game/are rejected -
Traversal detection —
..segments are rejected -
Segment-boundary containment —
/Game/AImust NOT match/Game/AIEvil
(prefix matching is not used; the next path segment must match) - Reserved namespace rejection — backup/state/journal roots are read-only for public writes
- Symlink/reparse check — Windows reparse points cannot escape the content root
Error codes:
UEBP.PATH_OUTSIDE_ALLOWED_ROOTUEBP.PATH_TRAVERSAL_DETECTEDUEBP.PATH_READ_ONLY_ROOTUEBP.PATH_INVALID_EXTENSION
Function and component targets are validated against a reviewed allow-list:
Allowed function examples:
KismetSystemLibrary::PrintStringKismetSystemLibrary::DrawDebugLine- Standard Blueprint math, string, array library functions
Denied function examples:
-
KismetSystemLibrary::ExecuteConsoleCommand→UEBP.REFLECTION_TARGET_DENIED - Any function not on the allow-list
Allowed component examples:
-
SceneComponent,StaticMeshComponent,SkeletalMeshComponent - Standard engine components
Denied component examples:
-
AudioComponent(until reviewed) →UEBP.REFLECTION_TARGET_DENIED
For patch operations, a sealed plan hash prevents plan substitution attacks:
Plan hash = SHA1( spec content hash + policy fingerprint + base fingerprint + current fingerprint )
Workflow:
-
PlanBlueprintPatchreturnsplanHash - AI must pass
expected_plan_hashtoApplyBlueprintPatch - Plugin recomputes hash on apply; mismatch →
UEBP.PLAN_HASH_MISMATCH - Empty/missing hash →
UEBP.PLAN_HASH_REQUIRED
The policy fingerprint (sha1:5308baef...) changes whenever security policy settings change, invalidating any previously planned patches — forcing a re-plan under the new policy.
Mutations are blocked on packages with unsaved changes from another source:
bDirty && !bOwnedByPlugin → UEBP.DIRTY_ASSET_PROTECTED
This prevents UEBPCracker from racing with manual editor changes.
Plugin-owned nodes (tracked by ownership manifest) are protected from mutation by other tools:
node not in ownership manifest → UEBP.UNMANAGED_CONTENT_PROTECTED
Only plugin-managed content can be patched via ApplyBlueprintPatch.
To prevent information leakage, the logging layer redacts sensitive data:
| Data type | Redaction |
|---|---|
| Absolute OS paths | <redacted-path> |
| Spec file content | <redacted-spec> |
| Secret/token values | <redacted> |
Redaction applies at all log verbosity levels including Verbose.
| Setting | Default | Notes |
|---|---|---|
| Bind address |
127.0.0.1 (loopback) |
bAllowRemoteMCPBind=False |
| Authentication | None | Never expose to LAN/internet |
| Protocol | HTTP (Unreal MCP SSE) | Not HTTPS in current UE 5.8 MCP |
| Port | Configurable (default 8000) | Firewall rules recommended |
⚠️ Do not setbAllowRemoteMCPBind=Trueon a machine accessible from the internet. The MCP protocol has no authentication layer.
| Code | Meaning |
|---|---|
UEBP.SECURITY_POLICY_DENIED |
Operation denied by general security policy |
UEBP.OPERATION_NOT_ALLOWED |
Operation type not permitted at current level |
UEBP.DESTRUCTIVE_OPERATIONS_DISABLED |
L3 is disabled in settings |
UEBP.DESTRUCTIVE_CONFIRMATION_REQUIRED |
Backup required before destructive op |
UEBP.PLAN_HASH_REQUIRED |
expected_plan_hash not provided |
UEBP.PLAN_HASH_MISMATCH |
Provided hash does not match recomputed hash |
UEBP.UNMANAGED_CONTENT_PROTECTED |
Target is not plugin-owned |
UEBP.DIRTY_ASSET_PROTECTED |
Target package has unsaved changes |
UEBP.REFLECTION_TARGET_DENIED |
Function or component not on allow-list |
UEBP.REMOTE_BIND_NOT_ALLOWED |
Remote bind attempted with bAllowRemoteMCPBind=False
|
UEBP.STATE_INTEGRITY_FAILED |
State/journal checksum mismatch |
UEBP.PATH_OUTSIDE_ALLOWED_ROOT |
Path outside configured content root |
UEBP.PATH_READ_ONLY_ROOT |
Path is in a read-only reserved namespace |
- Architecture — L0–L3 in the commit pipeline context
- Patch and Idempotency — how sealed plan hashes are used
- SECURITY.md — vulnerability reporting