Best Practices & First Principles: Custom Scripts
Custom Scripts are server-side JavaScript programs that run inside Metric Insights to collect data through the MI API and distribute it on Notification Schedules. Each script runs on behalf of a designated Authentication User and within the API access scope of an assigned External Application, so the choices made about identity and access shape everything the script can do. This article provides a general overview of what Custom Scripts are, how the system connects them to identity and access, which specialists are typically involved, and which choices must be made before building one. Use this article to settle the authentication model, evaluate whether a built-in feature already solves the need, and decide how parameters are managed before any code is written.
After reading this document, follow the Custom Scripts Workflow Playbook to execute the implementation phase by phase.
NOTE: This article does not cover the customScript object methods or debug mode. For the developer reference on runApiRequest, close, log, error, the parameters and homeSite properties, and debug mode, see Basic Practices for Custom Scripts Developers.
Table of Contents
1. What Are Custom Scripts
A Custom Script is a JavaScript program stored and executed inside Metric Insights. It calls the MI API to fetch or process data, then distributes the result, most commonly by attaching to a Notification Schedule so it runs as part of an automated workflow. Scripts can also be run manually for testing or on demand.
2. How Everything Works (Mental Model)
The system connects three layers for every script:
- External Application: Controls the API access scope for the script. It defines what the script's API token is permitted to reach.
- Authentication User: An MI user whose privileges the script inherits. The auto-generated API token acts on behalf of this user, so the user's privileges ARE the script's privileges.
- Parameters and Parameter Sets: Named inputs (referenced in code as
customScript.parameters.<name>) grouped into reusable configurations, so one script can serve multiple targets without code changes.
NOTE: Because a script acts as its Authentication User, any element the script creates shows that user as the creator, and every API call the script makes is limited to what that user is allowed to do.
3. Authentication Model
The most important decision before building a Custom Script is the identity it runs as. Two objects define this model, and both must be chosen deliberately:
- Authentication User: The MI user the script impersonates. The token generated for the script inherits exactly this user's privileges. Grant only the privileges the script genuinely needs.
- External Application: The object that scopes API access for the script. Its settings determine which parts of the API the token can reach.
Warning: An overprivileged Authentication User is the primary security risk with Custom Scripts. A script that only needs to read one Dataset should not run as a full administrator. Treat the Authentication User's privilege set as the script's blast radius and keep it minimal.
4. Decision Gates
Settle each gate below before implementation. Each has mutually exclusive options and a recommended default.
Gate A: Built-in feature vs Custom Script.
- Use a built-in feature (recommended when one exists): Native features require no code and are supported directly. For example, sending Metric images to a Slack channel is available as a configuration feature, so a Custom Script is unnecessary for that need. See Bursting to a Slack Channel.
- Build a Custom Script: Choose this only when no built-in feature covers the requirement, or when custom data processing or an external integration is required.
Gate B: Hardcoded values vs Parameters with Parameter Sets.
- Hardcode values: Fast to write, but fragile. Any change to a target, channel, or credential requires editing the code, and one script cannot serve multiple configurations.
- Use Parameters and Parameter Sets (recommended): Externalize each variable input as a Parameter and group configurations into Parameter Sets, so one script can run against many targets and can be edited without touching code. Mark a Parameter as
passwordtype to mask its value in the UI and run logs.
Gate C: Manual parameter setup vs the Setup CS Helper Custom App.
- Manual setup: Define each Parameter and Parameter Set by hand. Always available and requires no extra assets.
- Setup CS Helper Custom App: Automates parameter configuration. It requires assets obtained from [email protected] and an External Application with Application Can Manage Users enabled. Its auto-parameter features require the latest script build, which carries a Base64-encoded parameter definition. See How to Use the Setup CS Helper Custom App.
Warning: Older script builds that lack the Base64-encoded parameter definition break the automated parameter tooling in the Setup CS Helper Custom App. Confirm the script is on the latest build before relying on auto-parameter features.
5. First Principles
- Prefer a built-in feature over a script. Every Custom Script is code the customer must maintain. If a native feature meets the need, it is more supportable and secure than a bespoke script.
- Grant the Authentication User least privilege. The script inherits this user's privileges exactly. Scope the user to only what the script requires so a compromised or buggy script cannot reach beyond its purpose.
- Externalize configuration through Parameters. Keep channels, targets, and credentials out of the code and in Parameters and Parameter Sets, so the same script serves multiple configurations and can be re-targeted without a code change.
- Account for the acting-as-user side effect. Elements a script creates show the Authentication User as their creator. Choose a user whose identity is appropriate as the owner of everything the script produces.
6. Roles and Responsibilities
NOTE: A single individual can fulfill multiple roles, but the key is ensuring that all responsibilities are clearly assigned.
| Role | Responsibilities |
|---|---|
| Metric Insights Administrator | Creates and configures the External Application and Authentication User, attaches the script to Notification Schedules, and manages access and enablement of the script. |
| Script Developer | Writes the JavaScript, uses the customScript API, defines Parameters, and debugs the script. |
| Security / IAM Review | Reviews and approves the privileges granted to the Authentication User to enforce least privilege. |
7. Recommendations Before Start
- Confirm no built-in feature already covers the requirement before committing to a script; e.g., use Bursting to a Slack Channel instead of a Slack burst script where it fits.
- Provision a dedicated Authentication User scoped to least privilege rather than reusing a high-privilege account, and have Security review the grant.
- Create an External Application scoped to only the API access the script needs; enable Application Can Manage Users only if the Setup CS Helper Custom App will be used.
- Decide the parameter strategy up front: identify which values become Parameters and how Parameter Sets map to each configuration.
- If automated parameter tooling is planned, confirm the script is on the latest build carrying the Base64-encoded parameter definition, and obtain the required assets from [email protected].
- Verify the correct debug URL for the target platform version, as it differs between v6 and v7.
8. Readiness Checklist
- Built-in feature vs Custom Script decision made and documented (Gate A).
- Parameter strategy chosen (hardcoded vs Parameters with Parameter Sets) (Gate B).
- Parameter setup approach chosen (manual vs Setup CS Helper Custom App), with assets and the latest script build confirmed if automated (Gate C).
- Authentication User provisioned with least privilege and reviewed by Security / IAM.
- External Application created and scoped, with Application Can Manage Users set only where required.
- Roles assigned across Metric Insights Administrator, Script Developer, and Security / IAM Review.
- Correct debug URL confirmed for the platform version (v6 vs v7).
