Content Security Policy (CSP)
AlumnIQ sends a Content-Security-Policy response header on pages that need it (payment pages in particular — CSP is required for PCI compliance where we facilitate online payments). The policy tells the browser which off-site resources — fonts, images, scripts, styles, iframes, connections — are allowed to load. Anything not allowed is blocked by the browser.
This page documents the default policy and the knobs customers can turn when their branding or third-party integrations need additional sources allowed.
The default policy
The rules we ship, by directive:
| Directive | Allowed sources |
|---|---|
default-src | 'self' |
font-src | 'self', data:, any https: source |
img-src | 'self', data:, static.alumniq.com, s3.amazonaws.com, gravatar.com, gstatic.com, Facebook, Braintree, PayPal, GTM/GA |
style-src | 'self', 'unsafe-inline', 'unsafe-hashes', data:, static.alumniq.com, Spreedly, Datadog browser agent, Braintree, BootstrapCDN, Google Fonts |
script-src | 'self', 'unsafe-inline', static.alumniq.com, Facebook, Spreedly, Datadog browser agent, Braintree, PayPal, Google Pay, GTM/GA, CardinalCommerce (3DSecure) |
connect-src | 'self', Braintree, PayPal, Google Pay, google.com, CardinalCommerce, Facebook, Google Analytics, Sentry |
child-src | Braintree, PayPal |
frame-src | * |
font-src is deliberately wide open to any HTTPS source. We load fonts from customer CDNs for skinning purposes (e.g., a customer’s own type hosted on their university CDN), and locking this down would break those skins. If not for that, it would be restricted to static.alumniq.com plus the CDNs we actually use.
About 'unsafe-inline'
script-src and style-src both include 'unsafe-inline'. Braintree’s drop-in — which is how we offer digital wallets (PayPal, Apple Pay, Google Pay, Venmo) alongside regular card payments — requires it, and removing it breaks payment processing. It’s not ideal; inline script execution is exactly the hole CSP was designed to close. 'unsafe-inline' in style-src is lower-risk (just CSS) and we’re comfortable with that trade. In script-src it’s the line we had to give up to keep payments working.
About frame-src *
frame-src is set to *, meaning any origin may be loaded in an iframe on a CSP-protected page. We’d prefer a restrictive list here — payment iframes come from a small, known set of hosts (Spreedly, Braintree) — but 3DSecure (CardinalCommerce) does not publish an authoritative list of the hosts it may redirect through during a step-up challenge, and tightening frame-src has historically caused real customer transactions to fail. Until 3DSecure provides a concrete list, frame-src * is the pragmatic choice. The other directives (script-src, connect-src, child-src) remain tightly scoped, so the blast radius is limited to iframe embedding only.
Customer-specific additions
If your skin or integrations require additional off-site sources (e.g., fonts on a customer CDN we don’t already allow, a tracking pixel host, a custom analytics endpoint), AlumnIQ can add them to the policy for you.
What customers should be aware of
- Test payment and registration flows after changing anything in your skin that loads third-party assets. A new font host, a new tracking script, or a customer-hosted image CDN that isn’t on the allow-list will be silently blocked by the browser. The page will render, but resources linked from unallowed sources will be broken.
- Check the browser devtools console for CSP violations during QA. Blocked resources are logged as
Refused to load the ... because it violates the following Content Security Policy directive: .... That’s the fastest way to find out you need an addition. - Violations are reported back to AlumnIQ. Browsers will send violation reports to us via an automated reporting mechanism. We monitor these for unexpected breakage, but you’re the first line of defense since you’ll see them in your skin.
- GTM and GA4 are already allowed. You do not need to request additional entries to use Google Tag Manager or Google Analytics — those hosts are permitted by default. This does not include any plugins you’ve added to your containers. They always need explicit review and approval.
- The allow-list is per-customer, not per-page. An addition you request for one page of your skin will be present on every page that emits the CSP header.
- Changes go through a support ticket. To request additions, file a ticket with the resource, their privacy policy, and their SOC 2 attestation (if available) for us to review. We’ll assess and if they are deemed trustworthy we’ll add them to the allowlist. This is not a quick process but we’ll do our best.
Retrieving the current additions
The admin API exposes current customer additions at GET /api/v1/csp_additions, returning the per-directive additions in JSON. This is read-only; changes go through a support ticket.
You can also (with far less effort) view your current CSP status and inclusions in the admin console under Support > Content Security Policy.