Someone looking over my integration layer asked a simple question about the callout to SAP: is it secure? I answered without pausing — yes, it goes through a Named Credential. True, and almost useless.

What I had actually said was: the password is not in the code. That is worth being able to say, and it is not the same as “this callout is safe”. The gap between those two sentences is where a great many integration problems live, so let me lay out what a Named Credential does and what it quietly leaves on your desk.

What a Named Credential actually does

A Named Credential is a definition in Setup. It holds the endpoint URL of one external system and the authentication details for it, and your Apex refers to it by name rather than by address:

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:SAP_S4HANA/sap/opu/odata/sap/ZORDER_SRV/OrderSet');
req.setMethod('POST');
// no username, no client secret, no token in this file

Two real things follow.

The secret leaves your code. It is not in the class, not in source control, and not in a debug log waiting to be pasted into a support ticket.

The handshake becomes the platform’s job. For an OAuth connection the platform obtains the token, attaches it, and refreshes it when it expires — genuinely tedious code you no longer maintain.

That is a lot of value. It is not safety.

A Named Credential answers “how do I prove who I am?” It has no opinion at all about what you then say.

The three questions it does not answer

Everything the credential leaves behind fits into three questions, and all three belong to the developer:

  1. What is this callout allowed to send?
  2. Who authorised this particular call?
  3. Can I trust what comes back?

Question one: what goes into the payload

Your Apex builds the request body: it queries records, picks fields, serialises them into JSON, and hands the result to the platform, which authenticates it beautifully and posts it outside your org.

Now think about the query that built that body. If it ran in system mode, it read whatever it asked for, including fields the person who pressed the button is not permitted to see. Field-level security governs what appears on a screen; it does not follow the data into an outbound request unless your code makes it.

One version-dependent detail is worth checking first: in Apex below API version 67.0, plain SOQL runs in system mode, so field- and object-level permissions are not enforced by the Apex layer. From 67.0 onward, user mode became the default for plain operations. The version stamped on a class is therefore part of the answer to “what can this payload contain” — so look it up per class, and verify in your org.

The practical rule is smaller than the theory: build the payload from a query you would be happy for the running user to run, and send the fewest fields the receiving system needs. Every extra field in an outbound body is a field you have now exported.

Question two: authentication is not authorisation

Authentication asks who you are. Authorisation asks whether you may do this particular thing. A Named Credential settles the first and is silent on the second.

The remote side usually has its own opinion, and it is right to. In my TechnoStore build — a fictional B2B retailer living in a real Developer Edition org — orders are written into SAP S/4HANA with an OData v2 deep insert: a single request that creates a parent record and its child rows together. Being authenticated is not enough to perform one. S/4HANA requires an X-CSRF token handshake first: a GET that fetches a token, then the POST that carries it back. The Named Credential got me a session; the token exchange is what the write itself demanded.

Your side needs the same kind of gate, and nothing in Setup will build it for you. Before the callout fires, something in your code should decide: is this record in a state where sending is meaningful, and is this user permitted to trigger it? Without that check, any path that reaches your method — a Flow, a trigger, a quick action someone added last month — can push data outside your org, and the log will show a perfectly authenticated request.

Question three: the response is untrusted input

What comes back is a body you did not write. Check the status code before you parse, and validate the shape before you read fields out of it. Be slow to write a value into your org purely because a remote system asserted it — a wrong value delivered over a healthy connection is still a wrong value.

The inbound direction makes this vivid, because there the Named Credential does not apply at all: it governs calls going out. In that same TechnoStore build, nine external systems converge on one org through MuleSoft and direct Apex — SAP S/4HANA, Stripe, DocuSign, JIRA, Slack, Sendcloud/DHL, lexoffice, a DATEV export, and a CAMT.053 / ISO 20022 bank-statement parser. Every inbound webhook is verified with an HMAC-SHA256 signature before anything is written. Inbound trust is a separate mechanism you have to build yourself.

Delivered twice is normal, not sinister

Your credential setup will not stop the same message being applied twice either. Connections time out, providers redeliver, and a retry is ordinary life rather than an attack. The Stripe path in that build guards against it in two layers, and the second is the interesting half: before the webhook mutates anything, it checks the Order’s current status. If the order has already moved on, a repeated delivery finds nothing left to do. The state of your own data becomes the guard — so the protection survives even when the first layer is bypassed.

Sometimes the platform decides your shape

A last example, because it teaches a habit of mind. The DocuSign Connect webhook lands on a Salesforce Site, which runs as the Guest User — and the Guest User has real field-level-security limits. So the receiver does not write records directly: it publishes a Platform Event, and an autolaunched Flow does the write.

That extra hop is not an elegance. It exists because of a genuine platform constraint. Which is why, when you meet an integration with an odd-looking step in the middle, the first question is not “why is this so complicated?” but “which boundary put it here?”

Your next step

Open one outbound callout in an org you have access to and ask four questions. Where does its secret live? Which fields does its payload carry, and could the running user read every one of them? What decides that this call may happen at all? And what does the code do with a response that arrives malformed?

If the only answer you have is “it goes through a Named Credential”, you are standing where I was when that question caught me out. The credential unlocks the front door properly. What you carry through it, on whose authority, and what you accept on the way back are still yours.

Mustafa Aksu

Salesforce developer & ISV builder focused on Revenue Cloud, Agentforce, and Data Cloud. I write from real, shipped work.