All base collaborators will be able to access your automations.
One approach is to set up a dedicated ENV base so to speak where only you/admins have access and either pass hashed credentials/refresh tokens to other bases via Airtable API or have this base be your sole API calling base which feeds data into other bases as synced views/dataset.
To get straight to the point: Airtable doesn't have a native way for you to store environment variables or secrets in a comparable way to GCP or AWS' Secret Manager architecture services.
In a growing enterprise organization, I managed to skirt by with my script-side credential management using a variety of different approaches. Once I had to authenticate with a tightly guarded API, I realized my luck had run out and I needed to develop a scalable, easy-to-support approach to managing credentials in my scripts.
My solution was to write a microservice in Vercel that would verify the request for a credential and return the credential if the request is valid.
Here's an example of the workflow:
Presume I have a base with the ID of app12345. This base needs a Google Cloud Platform token scoped to delete objects from an S3 bucket in GCS.
In a locked down Airtable base, I maintain a "base of bases" where I am polling the Airtable API to provide me an up-to-date list of every base and table in the enterprise. There's a lot of nuance to it, but I also maintain a list of automations here.
In another table, I have records for every credential I need to index. It's important to note, credentials are never stored in Airtable. These credential records are just an abstraction layer. All credentials are stored solely in Vercel.
In this base, I relate credentials to the bases, automations, and blocks that should be given access to that credential.
An important thing to note about HTTP requests originating from Airtable is that the "x-airtable-source" header provides you a string of the originating base ID and either the automation workflow or block installation that made the request.
So, if I make a request from my example base, the x-airtable-source property will return "app12345/wfl12345."
If you make the request from a block (think custom extensions and scripting extensions), then you will get it in this format: "app12345/bli12345."
Now, when the microservice receives a request for a credential containing a request for a specific credential, the microservice will do a couple of things:
If all of those validations are satisfied, then the microservice returns the requested credential.
There are a couple of other layers that protect this entire process, nonetheless, the microservice averages a response time of two seconds depending on the time of day and the cost is negligible.