Bitta Apps
SolutionsPartnersAboutBlogPricingContact
Request a quote
Bitta Apps

Senior-led Business Central implementation, AL development, and Microsoft CSP licensing. Based in Corona, California. Remote-first across the U.S. and Canada, with onsite Southern California support by arrangement.

// services
  • Business Central partner
  • Implementation
  • AL Development
  • Integrations
  • Licensing & CSP
  • Support
  • QuickBooks migration
// industries
  • Distributors
  • Manufacturing
  • Retail
  • Healthcare
  • Non-Profit
  • Professional Services
// company
  • Solutions
  • Partners
  • Summit NA 2026
  • About
  • Careers
  • Blog
  • Pricing
  • Book a call
  • Contact
  • FAQ
// legal
  • Privacy
  • Terms
  • Cookies
  • EULA
[email protected]
LinkedIn
© 2026 · bittaapps.com · Microsoft Cloud Solution Provider[email protected]
    Back to blog

    // article

    AL Access Modifiers and Dependencies: Design a Stable Extension API

    by Bitta Apps·Aug 22, 2026
    Business CentralAL Development
    AL DevelopmentBusiness Central Extensions

    Every public AL symbol is a promise to dependent extensions. Once another app compiles against a table, codeunit, field, query, procedure, or interface, changing that symbol can turn an internal refactor into a customer upgrade failure.

    Access modifiers and explicit dependencies let an extension publisher control that promise. They do not replace permissions or data security; they shape the compile-time API surface.

    Default public access is a design decision

    The AL Access property applies to codeunits, queries, tables, table fields, enums, interfaces, and permission sets. Microsoft documents two values for objects, plus two more that are available only on table fields:

    • public: accessible from the same module and dependent modules; it is the default when Access is omitted.
    • internal: accessible inside the same module, with controlled test/friend access through internalsVisibleTo.
    • protected: a table-field-only value; the field can be accessed only by code in the same table or in table extensions of that table.
    • local: a table-field-only value; the field can be accessed only by code in the same table or table extension where the field is defined.

    Start new implementation objects as internal unless a documented consumer needs them. Make a symbol public only with a name, behavior, error contract, and compatibility policy that the team is willing to support.

    Access is not authorization

    Microsoft explicitly states that AL access modifiers are compile-time controls, not a security boundary. Reflection-style mechanisms can still reach data at runtime. Protect business data with entitlements, permission sets, object permissions, security filters where appropriate, and application validation.

    Publish contracts, not implementation tables

    A dependent app that writes directly to an implementation table bypasses invariants and makes schema refactoring difficult. Prefer a focused public codeunit or interface that expresses the supported operation. Keep storage, orchestration, and helper code internal.

    Interfaces reduce dependency on implementation details and enable multiple codeunit implementations. Microsoft advises keeping interfaces focused and avoiding incompatible additions to already-published interfaces. When a contract needs new mandatory behavior, publish a new interface version or a compatible extension pattern rather than silently breaking implementers.

    Declare dependencies deliberately

    An app dependency in app.json identifies the publisher, name, app ID, and minimum version of another extension. The minimum version is an operational statement: it tells Business Central which dependency release supplies the required contract.

    Do not raise minimum versions without a reason, because that can force a dependency upgrade for every customer. Do raise them when the app genuinely uses a symbol or behavior introduced later. Microsoft's library/dependency app guidance notes that a dependency is automatically updated when the consuming app requires a higher minimum version.

    Use a compatibility policy

    For each public contract, define changes as:

    • compatible: a new optional field, procedure, enum value handled by consumers, or implementation fix that preserves behavior;
    • conditionally compatible: a new event, default behavior, or performance characteristic that needs consumer testing;
    • breaking: removed/renamed symbols, changed types, required parameters, changed key semantics, or incompatible behavior.

    A breaking change should use a new contract version, an obsoletion period where possible, migration notes, and coordinated testing with dependent apps.

    Keep compile-time visibility separate from runtime authorization

    An access modifier determines which AL code can reference a symbol when extensions compile. It does not decide whether a user can read a table, execute a page, or perform a business action at runtime. Those controls still belong in permission sets, entitlements where applicable, and the authorization checks of the business workflow.

    This separation prevents a dangerous review mistake. A public procedure is not automatically available to every user, and an internal procedure is not automatically secure. Review the extension contract and the runtime permission model as two connected but independent layers, then test both with the identities that will operate the app.

    Protect the API in CI

    1. Compile known dependent apps against the release candidate.
    2. Run analyzers and fail on newly exposed symbols that lack review.
    3. Compare symbols or generated documentation between releases.
    4. Test dependency installation and upgrade ordering.
    5. Validate against the next Business Central preview.
    6. Publish deprecation and minimum-version changes in release notes.

    A practical review

    For every public object or procedure, ask: who consumes it, what behavior is guaranteed, how is it authorized, how will it evolve, and how is it tested? If there is no clear consumer, it probably belongs behind an internal boundary.

    Bitta Apps can review extension boundaries, refactor shared libraries, and establish compatibility checks through Business Central AL development, with release support for customer and Marketplace dependency chains.

    // next step

    Talk to a senior Business Central consultant, not a sales rep.

    Fixed-price proposal in writing within five business days of discovery.

    Request a quoteBook a call

    // keep reading

    CI/CD for Business Central AL Extensions: A Release Pipeline That Protects Customers

    Build a traceable AL release pipeline with reproducible artifacts, analyzers, automated tests, sandbox deployment, approvals, and rollback evidence.

    Business Central Web Service Performance: Fast, Resilient API Patterns

    Improve Business Central integration performance with API pages, bounded payloads, paging, OAuth, idempotency, controlled concurrency, and telemetry.

    Business Central AL Page Design: Patterns That Age Well

    Design Business Central AL pages around user tasks, supported page types, predictable actions, efficient data access, accessibility, and testability.