CtrlK
BlogDocsLog inGet started
Tessl Logo

bc-skills/controlling-al-access

Control AL object visibility with Access property (Public, Internal, Protected, Local)

—

—
Quality

—

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

—

The risk profile of this skill

Overview
Eval results
Files
name:
controlling-al-access
description:
Controls visibility of AL objects and fields using Access property (Public, Internal, Protected, Local), hides internal helpers from external apps, exposes public API surfaces, and configures internalsVisibleTo for multi-app scenarios. Use when making codeunits private, hiding staging tables, protecting fields from partners, or sharing internals between companion apps.
license:
MIT
metadata:
{"version":"1.0.0"}

Skill: AL Access Modifiers

Validation Gates

  1. After Step 1: Internal objects compile, external apps get "not accessible" compile error
  2. After Step 2: Field access levels work (test: Local field inaccessible outside table)
  3. Final: internalsVisibleTo apps 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 <ID> "<PREFIX> Internal Staging"
{
    Access = Internal;
    // ... fields
}

// Internal codeunit - helper not exposed to partners
codeunit <ID> "<PREFIX> Internal Helper"
{
    Access = Internal;
    // ... procedures
}

Step 2: Set Field Access

table <ID> "<PREFIX> 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

LevelSame TableTable ExtensionSame AppOther 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": "<companion-app-guid>", "name": "Companion App", "publisher": "My Publisher" },
        { "id": "<test-app-guid>", "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 <ID> "<PREFIX> Public API"
{
    Access = Public;
    procedure ProcessOperation(InputData: Text): Boolean
    begin
        exit(InternalProcessor.DoProcess(InputData));
    end;
    var
        InternalProcessor: Codeunit "<PREFIX> Internal Processor";
}

codeunit <ID+1> "<PREFIX> Internal Processor"
{
    Access = Internal;
    procedure DoProcess(InputData: Text): Boolean
    begin
        // Can be refactored freely - not exposed
    end;
}

Secret Management

codeunit <ID> "<PREFIX> Secret Manager"
{
    Access = Internal;
    [NonDebuggable]
    procedure GetClientSecret(): Text
    begin
        // Use IsolatedStorage with DataScope::Module
    end;
}

Quick Reference

ScenarioRecommended Access
Stable API for partnersPublic
Helper codeunitsInternal
Staging/buffer tablesInternal
Fields for table extensionsProtected
Fields in table triggers onlyLocal
Secret managementInternal + [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

  • Access Property
  • Access Modifiers
  • internalsVisibleTo
Workspace
bc-skills
Visibility
Public
Created
Last updated
Publish Source
CLI
Badge
bc-skills/controlling-al-access badge