Secrets
Module 8 of 8 in the chapter Trust, Identity, and Integration Security, chapter 13 of the Integration Architect course. Each module stands on its own. Previous: Tokens as a Design Decision · Back to the chapter: Trust, Identity, and Integration Security
The question this module answers: Where do an integration’s secrets belong, where must they never be, and how do you practise with them safely?
The Secret in the Description Field
Section titled “The Secret in the Description Field”Remember the partner door from module 3? An attacker used a vendor’s stolen tokens to export data from many orgs. Then they did something that tells you exactly what they were after. They searched the stolen records for secrets: “sensitive credentials such as Amazon Web Services (AWS) access keys (AKIA), passwords, and Snowflake-related access tokens” (Widespread Data Theft Targets Salesforce Instances via Salesloft Drift (opens in a new tab), Google Threat Intelligence, August 26, 2025, checked 2026-11-07).
Why would those be in CRM records? Because someone pasted them there. An admin troubleshooting an integration put the key in a case comment. A developer left a password in a description field so the next person could find it. The ordinary CRM data was bad enough to lose. The secrets inside it opened the next door.
Don’t create a really strong locked door and then leave the back door open. Everything in this chapter, the identities, the flows, the tokens, is the locked door. Where the secrets sit is the back door.
Where Secrets Live
Section titled “Where Secrets Live”A few right homes, all built for it; many wrong ones, none of them meant for it.
Places built to hold them:
- Salesforce’s named and external credentials, for every secret Salesforce uses to call out. The external credential keeps it encrypted, and only the people and processes you allow can use it (chapter 4).
- The other system’s own secret store, for the client ID and secret it uses to call in: the integration layer’s vault, a cloud’s secret manager. Never its configuration file.
- On your own bench, a local vault. Postman’s, in the lab below, is one.
And each secret gets an owner and a rotation date, like every certificate in chapter 12.
Places never meant to hold them: a record, any field, any note, any comment; code, a flow, or a file in source control; an email, a chat message or a ticket; and an AI tool’s prompt.
That last one is new, and it matters more every month. Never paste a secret into an AI tool. Not to debug a failing callout, not to ask why a token was refused. Give it the error, the request with the secret replaced by a placeholder, the configuration without the values. An AI doesn’t need your secret to help you, and once it’s in a prompt, you don’t control where it goes.
When One Leaks
Section titled “When One Leaks”If a secret has been somewhere it shouldn’t, assume it’s been seen. Then the order matters:
- Rotate it first. Issue a new secret, put it where it belongs, and confirm the integration works with it.
- Revoke what it gave out. Every token the old secret produced, at
/services/oauth2/revoke(module 7). - Then remove it from the record, the file, the message. Removing it first only hides that it leaked.
- Then look at what it was used for while it was out (chapter 14).
And go looking before anyone else does. Search your own records for the shapes secrets take: AKIA, password, secret, token, Bearer. You may be surprised what’s there.
Your Lab Bench
Section titled “Your Lab Bench”Now practise it, safely. In 2023 I showed the Postman demo with the username-password flow. That flow retires on February 20, 2027, so here’s the bench rebuilt: two External Client Apps, the two current flows, and no password anywhere except Salesforce’s own login page.
The same rules on your bench as in production.
You’ll need a Developer Edition org of your own, Postman, and the Postman setup from chapter 2.
1. Create the External Client Apps. In Setup, enter external client in the Quick Find box, select External Client App Manager, and click New External Client App. Expand API (Enable OAuth Settings) and select Enable OAuth. Make two:
- Bench — server. Enable the client credentials flow, choose an integration user for it to run as in the app’s policies (module 4), and give it the api scope.
- Bench — person. For the callback URL, enter
https://oauth.pstmn.io/v1/callback(orhttps://oauth.pstmn.io/v1/browser-callbackif you use Postman in a browser), and give it the api and refresh_token scopes.
Salesforce warns that a new External Client App “can take up to 30 minutes to become available” (Create an External Client App (opens in a new tab), Salesforce Developers, checked 2026-11-07). Get a coffee.
2. Put the secrets in the vault. From each app, copy the consumer key, and for the server app, the consumer secret. In Postman, put them in your local vault: “Only you can access vault secrets in your Postman Local Vault, and they aren’t synced to the Postman Cloud” (Store secrets in Postman Vault (opens in a new tab), Postman Docs, checked 2026-11-07). From now on, your requests say {{vault:bench-server-secret}}, never the secret itself.
3. Client credentials: the food festival. On a new request, open Authorization, choose OAuth 2.0, and configure a new token: Grant Type Client Credentials; Access Token URL https://YourMyDomain.my.salesforce.com/services/oauth2/token; Client ID {{vault:bench-server-key}}; Client Secret {{vault:bench-server-secret}}. Use your My Domain address: for this flow, “requests to https://login.salesforce.com (opens in a new tab) and https://test.salesforce.com (opens in a new tab) aren’t supported” (OAuth 2.0 Client Credentials Flow for Server-to-Server Integration (opens in a new tab), Salesforce Help, checked 2026-11-07). Get the token.
4. The web server flow with PKCE: the burger house. On a second request, configure a new token: Grant Type Authorization Code (With PKCE); select Authorize using browser; Auth URL https://YourMyDomain.my.salesforce.com/services/oauth2/authorize; Access Token URL the same token address as step 3; Client ID {{vault:bench-person-key}}; Client Secret left blank; Code Challenge Method SHA-256; Code Verifier left blank, so Postman makes one; Scope api refresh_token. These settings follow Salesforce’s own Postman guide, adapted from its MCP servers to the REST API (Configure Postman (opens in a new tab), Salesforce Developers, checked 2026-11-07). Get the token: the browser opens Salesforce’s login page, you sign in there, and Postman receives the token. The pickup word from module 5 is the code verifier Postman made.
5. Call, compare, revoke. Look at each token response first. Alongside the access token, Salesforce returns an id, the identity URL, which names the user the token belongs to. Compare them: the first is the integration user you chose; the second is you. Same org, two identities, decided by the flow. Then send the same request with each token:
GET https://YourMyDomain.my.salesforce.com/services/data/v68.0/limitsand try a query on an object the integration user can’t see, to watch the permission set do its job. And when you’re done, revoke both tokens:
POST https://YourMyDomain.my.salesforce.com/services/oauth2/revokeContent-Type: application/x-www-form-urlencoded
token={{the refresh or access token}}Revoking is the habit. A bench left with live tokens is a bench someone else can use.
One more thing to notice. Postman doesn’t sync a token to its cloud unless you tell it to: “By default, Postman won’t sync your token in case you don’t want to share it” (Authenticate with OAuth 2.0 authentication in Postman (opens in a new tab), Postman Docs, checked 2026-11-07). Leave it that way.
What the Chapter Adds Up To
Section titled “What the Chapter Adds Up To”Eight modules, one picture of a trusted integration:
- It’s built knowing security keeps changing (module 1).
- What crosses is protected past the channel, and some things never travel (module 2).
- Its three doors are closed: no app anyone can approve, no token that does too much, no guest that sees too much (module 3).
- It has its own identity, behind five gates (module 4).
- It uses the right flow for its caller (module 5).
- It’s built on an External Client App coming in and a named credential going out (module 6).
- Its tokens rotate, expire when idle, can be taken back, and work only where they should (module 7).
- And its secrets live only where they belong (module 8).
Test knowledge. Store outbound secrets in named and external credentials, never in code, records or custom fields an admin can read; keep a client’s secret in its own secret store. If a secret leaks: rotate, revoke the tokens it issued, then remove it. Client credentials token requests go to the My Domain URL, not login.salesforce.com or test.salesforce.com. A PKCE client can omit the client secret.
What an Architect Decides Here
Section titled “What an Architect Decides Here”- Where every secret lives, for every integration, in and out, with an owner and a rotation date.
- The rule for records, code, tickets and AI tools: no secrets, written into the team’s standards, and checked.
- The leak runbook: rotate, revoke, remove, review, and who does each.
- The search that finds secrets already sitting in records, and how often it runs.
- A bench for every developer that follows the same rules as production.
Explore
Section titled “Explore”- OAuth 2.0 Client Credentials Flow for Server-to-Server Integration (opens in a new tab): Salesforce Help (checked 2026-11-07)
- Create an External Client App (opens in a new tab) and Configure Postman (opens in a new tab): Salesforce Developers, Hosted MCP Servers (checked 2026-11-07)
- Store secrets in Postman Vault (opens in a new tab), Use vault secrets in Postman (opens in a new tab) and Authenticate with OAuth 2.0 authentication in Postman (opens in a new tab): Postman Docs (checked 2026-11-07)
- Widespread Data Theft Targets Salesforce Instances via Salesloft Drift (opens in a new tab): Google Threat Intelligence, August 26, 2025 (checked 2026-11-07)
