Data / ML · Security

Acumatica Field-Level Encryption — A Complete Guide

Acumatica encrypts a handful of sensitive fields out of the box, PXRSACryptString lets you encrypt custom fields at the application layer, and neither is the same thing as hiding a column from a role in the UI.

John Kihiu12 min read

"Is Acumatica encrypted?" is a question I get from client security teams often enough that I've learned to answer it in three separate parts, because the honest answer is "yes, no, and it depends on what you mean" and giving the one-word version to an auditor is how you end up with a finding. There's platform-level encryption you don't control, a specific attribute you can apply to your own custom fields, and a UI feature that looks like encryption but isn't. Conflating any two of those three is the mistake I see most.

What Acumatica encrypts by default

Out of the box, Acumatica encrypts a specific, short list of sensitive fields: credit card numbers, email account credentials (the passwords you store when configuring an outbound mail account), SMS account credentials, and user login passwords. This isn't a setting you toggle — it's built into the DACs that hold these values, and it happens whether or not anyone on the implementation team ever thinks about it. It's also a narrow list. It does not mean every column that looks sensitive is encrypted, and it's a common wrong assumption that because Acumatica "does encryption," a custom field holding, say, a national ID number or a bank account reference gets the same treatment automatically. It doesn't. If it's not on that short built-in list, it's stored as plain text unless you do something about it.

PXRSACryptString: encryption for fields you add

For a custom text field that needs the same protection, Acumatica exposes the PXRSACryptString attribute. Apply it to a field in a customization and Acumatica handles the encryption using the RSA algorithm from the .NET cryptography libraries — key management is automatic, the value is encrypted before it's written to disk, and it's decrypted back into memory when the record is read. You don't write the crypto code yourself; you declare the field and the platform does the rest.

C# · DAC extension
public class UsrIDNumberExt : PXCacheExtension<Contact>
{
    #region UsrNationalID
    [PXDBString(20, IsUnicode = true)]
    [PXRSACryptString]
    [PXUIField(DisplayName = "National ID Number")]
    public virtual string UsrNationalID { get; set; }
    public abstract class usrNationalID : PX.Data.BQL.BqlString.Field<usrNationalID> { }
    #endregion
}

The value round-trips transparently for anyone with access to the screen — a user with the right role sees the plain value in the field, same as before. What changes is what's sitting in the database: the raw column holds ciphertext, not the ID number itself, so a database-level breach or a leaked backup doesn't hand over the value in the clear.

This is one column, not a security program

PXRSACryptString protects the specific field you apply it to. It does nothing for the other twenty columns on the same DAC, doesn't touch the field in any GI, report, or export that reads it after decryption, and doesn't stop a user with legitimate access to the screen from seeing the plain value. Decide field-by-field, based on what's actually sensitive, rather than assuming one encrypted column means the customer record is "secured."

Not the same as Acumatica Cloud's infrastructure encryption

If your instance is hosted on Acumatica Cloud, the hosting provider is separately handling encryption at the infrastructure level — data at rest via AES-256 on the underlying storage, and TLS for data in transit between the browser and the application. That's a platform control that protects the entire database, and it exists regardless of whether you've applied PXRSACryptString to a single field. The two are complementary, not redundant: infrastructure encryption protects against someone getting at the raw disk or intercepting network traffic; PXRSACryptString protects a specific value even from someone with query access to the live database or an unencrypted backup export. Telling a client "we're on Acumatica Cloud so it's encrypted" answers the infrastructure question and skips the application-layer one — both come up in a serious security review, and they're answered differently.

Hiding a field from a role is not encrypting it

The third piece is UI-level field access — restricting which roles can see a column like an SSN or salary figure on a screen, whether through field-level security settings or conditionally hiding it in a customization. This is a real and useful access control, and it's worth doing. But it's not encryption. The value still sits in the database in plain text (or in whatever form it was already in); you've only changed who gets to look at it through that one screen. Anyone with direct database access, API access to the field, or a different screen that happens to expose the same DAC field without the same restriction can still read it. I've had clients describe this as "we encrypt SSNs" when what they'd actually built was a role-based display rule, and the distinction matters the moment someone asks what happens if the database itself is compromised — the honest answer, in that setup, is that it doesn't help at all.

Deciding which fields actually need it

In practice, I reserve PXRSACryptString for fields that are genuinely sensitive on their own — national ID numbers, bank account details you're forced to store outside a proper payment vault, anything that would be a real problem if it leaked in a backup. I don't reach for it as a default on every custom field, because it adds decrypt overhead on every read and makes the field unusable in raw SQL-level reporting without extra work. For fields that just need to be hidden from most users but aren't independently dangerous if a DBA sees them, UI-level restriction is the right-sized answer, not encryption.

Wrapping up

Acumatica encrypts a short, fixed list of sensitive fields automatically — passwords, card numbers, account credentials. PXRSACryptString extends that same protection to your own custom fields, with the platform handling RSA encryption and key management for you. Acumatica Cloud's AES-256-at-rest and TLS-in-transit are a separate, infrastructure-level control that protects the whole database regardless of what you've done at the field level. And restricting a field's visibility by role is an access control, not encryption — the value is still there in plain text for anyone who reaches it a different way. Get those three things confused in front of an auditor and you'll spend the meeting walking it back.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.