Install
$ agentstack add skill-emgreppi-business-central-ai-skill-controlling-al-access ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: AL Access Modifiers
Validation Gates
- After Step 1: Internal objects compile, external apps get "not accessible" compile error
- After Step 2: Field access levels work (test: Local field inaccessible outside table)
- Final:
internalsVisibleToapps can access internal objects
Note: BC 2019 Wave 2+ (Runtime 4.0). Compile-time only - RecordRef/FieldRef bypass at runtime.
Output: Objects with correct Access property, app.json with internalsVisibleTo (if multi-app).
Supported objects: Codeunit, Table, Table field, Query, Enum, Interface, PermissionSet
Procedure
Step 1: Set Object Access
// Internal table - hidden from external apps
table " Internal Staging"
{
Access = Internal;
// ... fields
}
// Internal codeunit - helper not exposed to partners
codeunit " Internal Helper"
{
Access = Internal;
// ... procedures
}
Step 2: Set Field Access
table " Order Extension"
{
Access = Public;
fields
{
field(1; "Order No."; Code[20]) { Access = Public; } // Stable API
field(2; "Processing Flags"; Integer) { Access = Internal; } // Same app only
field(3; "Extension Point"; Code[50]) { Access = Protected; } // Table extensions
field(4; "Internal Counter"; Integer) { Access = Local; } // This table only
}
}
Access Level Summary
| Level | Same Table | Table Extension | Same App | Other Apps | |-------------|------------|-----------------|----------|------------| | Local | ✓ | | | | | Protected | ✓ | ✓ | | | | Internal | ✓ | ✓ | ✓ | | | Public | ✓ | ✓ | ✓ | ✓ |
Designer note: Only Public fields appear in in-client Designer.
Step 3: Configure internalsVisibleTo (Multi-App)
In app.json of the core app:
{
"internalsVisibleTo": [
{ "id": "", "name": "Companion App", "publisher": "My Publisher" },
{ "id": "", "name": "Test App", "publisher": "My Publisher" }
]
}
Use cases: Core + Companion apps, Test apps accessing internals, Modular architecture.
Important Notes
⚠️ NOT a security boundary: Access is compile-time only. RecordRef/FieldRef bypass at runtime. Use permission sets for data security.
Design Patterns
Public API + Internal Implementation
codeunit " Public API"
{
Access = Public;
procedure ProcessOperation(InputData: Text): Boolean
begin
exit(InternalProcessor.DoProcess(InputData));
end;
var
InternalProcessor: Codeunit " Internal Processor";
}
codeunit " Internal Processor"
{
Access = Internal;
procedure DoProcess(InputData: Text): Boolean
begin
// Can be refactored freely - not exposed
end;
}
Secret Management
codeunit " Secret Manager"
{
Access = Internal;
[NonDebuggable]
procedure GetClientSecret(): Text
begin
// Use IsolatedStorage with DataScope::Module
end;
}
Quick Reference
| Scenario | Recommended Access | |----------|-------------------| | Stable API for partners | Public | | Helper codeunits | Internal | | Staging/buffer tables | Internal | | Fields for table extensions | Protected | | Fields in table triggers only | Local | | Secret management | Internal + [NonDebuggable] |
Guidelines: Default to Internal • Public = supported contract • Changing Public → Internal is breaking
Limitations: Cannot set on Pages, Reports, XMLports, Control add-ins.
External Documentation
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: emgreppi
- Source: emgreppi/Business-Central-AI-Skill
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.