Skip to content

fix: enforce SAP_ALLOWED_PACKAGES on existing-object mutations#101

Merged
oisee merged 4 commits intomainfrom
pr-93-fix
Apr 12, 2026
Merged

fix: enforce SAP_ALLOWED_PACKAGES on existing-object mutations#101
oisee merged 4 commits intomainfrom
pr-93-fix

Conversation

@oisee
Copy link
Copy Markdown
Owner

@oisee oisee commented Apr 11, 2026

Summary

  • SAP_ALLOWED_PACKAGES was only enforced on object creation paths, not on existing-object mutations
  • Added checkObjectPackageSafety to all write paths: EditSource, WriteProgram, WriteClass, WriteSource (update path), RenameObject, UpdateSource, DeleteObject, CreateTestInclude, UpdateClassInclude, WriteMessageClassTexts, WriteDataElementLabels
  • UI5 BSP mutation paths (UI5UploadFile, UI5DeleteFile, UI5DeleteApp) remain as follow-up — needs app-to-package resolution

Reported by Philip Dolker.

Test plan

  • All existing tests pass (go test ./...)
  • Existing checkObjectPackageSafety normalization tests pass
  • Existing UpdateSource/DeleteObject/CreateTestInclude/WriteMessageClassTexts enforcement tests pass
  • Integration test: configure SAP_ALLOWED_PACKAGES=$TMP and verify EditSource on a non-$TMP object is blocked
  • Follow-up: UI5 BSP app-to-package resolution for upload/delete enforcement

🤖 Generated with Claude Code

oisee and others added 4 commits April 11, 2026 22:39
AllowedPackages was only checked on object creation flows (CreateObject,
CreateAndActivateProgram, CreateClassWithTests). Existing-object mutations
via EditSource, WriteProgram, WriteClass, WriteSource, RenameObject, and
low-level UpdateSource/DeleteObject/CreateTestInclude/UpdateClassInclude
bypassed the package restriction entirely.

Added checkObjectPackageSafety (resolves package via SearchObject) to all
write paths operating on existing objects. Also hardened i18n writes
(WriteMessageClassTexts, WriteDataElementLabels) and added transportable
edit checks where missing. UI5 BSP mutation paths remain as a tracked
follow-up (needs app-to-package resolution).

Reported by Philip Dolker.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary of the package safety fix session: bug diagnosis, root cause,
functions hardened, test coverage, remaining UI5 gap, and pending actions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidates operation-type, package-ownership, and transportable-edit
checks behind a single `checkMutation(ctx, MutationContext)` call in a
new pkg/adt/mutation_gate.go. Every mutator (CRUD, workflows, i18n, UI5)
now passes through this gate with an explicit context describing what
it intends to do, instead of wiring three separate sub-checks by hand.

This closes a whole class of "forgot one sub-check" bugs: the package
enforcement bug fixed in the prior commit happened because EditSource
etc. had an op-type check but no package check. The unified gate makes
that omission impossible — you either call checkMutation (which does
all three) or you don't gate at all (obvious at review time).

Surfaces:
  - SurfaceADT: resolves package via SearchObject for existing objects
  - SurfaceUI5: no app→package resolver yet, so mutations fail closed
    when AllowedPackages is configured (was previously a silent bypass)

Precedence: explicit Package > resolve via ObjectURL > fail closed with
a clear error naming the op.

Behavior change: UI5UploadFile, UI5DeleteFile, and UI5DeleteApp now
block when SAP_ALLOWED_PACKAGES is set. They were previously unguarded.
Users combining AllowedPackages with UI5 writes will see a clear error
directing them to the follow-up (UI5 app→package resolution).

Tests:
  - New pkg/adt/mutation_gate_test.go covering op-type block,
    explicit-package block, ObjectURL resolution, UI5 fail-closed, UI5
    pass-when-no-policy, fail-closed on missing context, and end-to-end
    UI5UploadFile/DeleteFile/DeleteApp blocking
  - Existing tests still pass (go test ./... clean)

Reviewed by Codex.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 1 (08e3d78) added package checks to individual mutators.
Phase 2 (c3a5341) consolidated them behind a single checkMutation gate
and closed the UI5 fail-closed gap. Report now covers both phases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@oisee oisee merged commit 0713d75 into main Apr 12, 2026
@MagPasulke
Copy link
Copy Markdown

Uff, that was fast! Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants