Authenticating to external systems from a module
When a function needs to sign in to an external system — a Teamwork Cloud server, Google Drive, a Windchill server, or any API behind a login — your module declares an authentication input. At run time the agent hands your function a ready-to-use sign-in, and your code reads it like any other input.
The contract in two steps
- Declare an input of type
auth_infoin yourmodule_manifest.json, tagged with the kind of sign-in your function needs. - Read that input at run time: its value is a path to a JSON file the agent prepared for this job. Open the file and use the secret inside.
Everything else — securely encrypting the secret, delivering it only to the agent that runs the job, refreshing tokens, and scrubbing the credentials — is handled by the platform.
Step 1 — Declare the authentication input
Add an input with "type": "auth_info" to your function's input schema. Tag it with a validation type of the form @<standard>:<provider>, which tells the platform what kind of sign-in to deliver:
"twc_login": {
"type": "auth_info",
"validation_types": ["@oauth2:teamwork_cloud"],
"display_name": "Teamwork Cloud sign-in"
}
The input name (twc_login above) is yours to choose — it is the key you read back at run time.
Standards (<standard>):
| Standard | Use it for |
|---|---|
oauth2 | OAuth2 / OIDC browser sign-in (access tokens) |
basic | Username-and-password sign-in |
token | A self-managed API key or personal access token |
Providers (<provider>) name the external application:
| Provider | Application |
|---|---|
teamwork_cloud | Teamwork Cloud |
google_accounts | Google Workspace |
windchill | Windchill |
dassault_3d_passport | 3D Experience |
microsoft_entra | Microsoft 365 |
For example, @oauth2:teamwork_cloud requests an OAuth token for Teamwork Cloud, and @basic:windchill requests a Windchill username and password. The provider must match an integration an administrator has configured for the kind of credential you need.
Keep functions that take a connected (linked) file separate from functions that take a local file. If a function reads a file from an external service it usually needs a matching auth_info input; a function that only processes a local upload does not. Put them in separate function variants so the platform can route each job correctly.
Step 2 — Read the credential at run time
The agent writes all of your function's inputs into the input JSON file. Your authentication input appears there as {"type": "auth_info", "value": "<path>"}, where value is the path to a JSON file the agent decrypted to disk for this job. Open that file and read the sign-in:
import json
import sys
# The agent invokes your entrypoint with the paths named in the manifest's
# run_command — "{entrypoint} {input_file} {output_file} {temp_dir}" — so the
# first argument is the input JSON file holding all of your function's inputs.
input_file = sys.argv[1]
with open(input_file) as f:
inputs = json.load(f)
# The auth input's value is a path to the prepared sign-in file.
secret_path = inputs["twc_login"]["value"]
with open(secret_path) as f:
secret = json.load(f)
access_token = secret["token"]
auth_server = secret["authentication_server"]
The keys in the sign-in file depend on the standard you requested:
| Standard | Keys in the delivered JSON |
|---|---|
oauth2 | token (the access token) and authentication_server (the issuer URL). The token is also available as access_token and auth_token. |
basic | username and password. |
token | token (also available as api_key). |
A basic sign-in is read the same way — open the file path, parse the JSON:
secret_path = inputs["windchill_login"]["value"]
with open(secret_path) as f:
secret = json.load(f)
username = secret["username"]
password = secret["password"]
The pattern is identical in any language. For example, in Java:
String json = new String(Files.readAllBytes(
Paths.get(functionInput.getTwcLogin().getValue())));
TwcLogin login = Serialization.deserializeJson(json, TwcLogin.class);
// login.getToken() + login.getAuthenticationServer() for OAuth2,
// or login.getUsername() + login.getPassword() for Basic.
Where the credential comes from
Your module reads the credential the same way in both of the cases below.
Using an admin-configured integration
This is the typical case for a shared system such as a Teamwork Cloud connection or a Windchill service account.
- An administrator connects the application once and either creates a shared service account or lets users link their own accounts.
- When a user launches a job that uses your function, they pick a credential in the launcher. The platform delivers it to the agent.
- Your function reads it from the
auth_infoinput as shown above.
Declare the input with the provider for that application — for example @oauth2:teamwork_cloud or @basic:windchill.
Using a token each user supplies
Use this when each user should authenticate with their own token rather than a shared, admin-managed account — for example a personal access token for a third-party API.
- The user adds their own token to their Linked Accounts (a personal API token or a username-and-password login).
- When launching a job, the user selects that personal credential. Nothing is stored on the queued job; the token is delivered to the agent only when the job runs.
- Your function reads it from the
auth_infoinput exactly as above.
Declare the input with @token:<provider> for an API key or personal access token, or @basic:<provider> for a username and password. No administrator setup is required beyond the user having a token to supply.
Security notes
- The sign-in your function receives is short-lived and single-use, encrypted so that only the agent running the job can read it, and removed when the job finishes — even if it fails.
- Treat the secret like any other credential: use it for the sign-in and never write it to logs, outputs, or artifacts.
Related pages
- App Integrations — how administrators connect applications and create service accounts.
- Module Manifest API Reference — the full input schema, including
auth_info. - Integrations, jobs, and agents — the concepts behind authenticated jobs.