JoinPPA.org¶
joinppa.org is part of the Procurement Professionals Alliance portfolio maintained and supported by Online Services.
Repository¶
| Item | Value |
|---|---|
| GitHub repository | NASPO-ValuePoint/joinppa |
| Canonical local path | ~/Sites/naspo/joinppa.org |
Environment and Deployment Model¶
JoinPPA uses separate development, staging, and production deployment workflows.
| Branch | GitHub Environment | Deployment behavior |
|---|---|---|
dev |
dev |
Automatic on push to dev; workflow can also be started manually |
staging |
staging |
Automatic on push to staging; workflow can also be started manually |
main |
prod |
Manual workflow_dispatch only; workflow is guarded to run only from main |
The workflows connect to the matching server through Tailscale using tag:ci, then SSH to the configured server/user from GitHub Environment variables.
Required GitHub Environment variables:
SERVER_HOSTSERVER_USERSITE_PATH
Deployment secrets include Tailscale OAuth credentials and environment-specific deploy SSH keys. Do not copy secret values into OSKB.
Hosting and DNS¶
JoinPPA runs on AWS Lightsail. Environment routing must be confirmed from DNS and Cloudflare, not from Lightsail instance names alone.
Environment status last verified August 12, 2026:
| Instance | Address | Current role |
|---|---|---|
joinppa-prod |
100.57.162.108 |
Live production origin after the August 12, 2026 DNS correction |
joinppa-staging |
32.196.145.231 |
Staging |
joinppa-dev |
3.226.249.23 |
Development |
joinppa |
44.213.124.78 |
Previous production origin, retained temporarily for reconciliation review |
Before August 12, 2026, production Cloudflare DNS still pointed joinppa.org traffic to the older joinppa instance at 44.213.124.78, even though joinppa-prod had already been prepared as the intended production environment. DNS was changed on August 12, 2026 so production traffic now reaches joinppa-prod at 100.57.162.108.
The older joinppa instance has not been destroyed. Keep it available until Online Services confirms whether content or configuration needs to be reconciled before retirement.
Cloudflare proxies the public JoinPPA DNS records. joinppa.org redirects to the canonical production URL:
Server Layout¶
The production server uses a Debian/Apache-style layout. It does not use the Bitnami layout used by some other NASPO properties.
The workflows verify that /var/www/html exists on the target server. WordPress is deployed under the configured SITE_PATH, and the production server layout last verified August 12, 2026 uses:
/var/www/wp-config.php/var/www/htmlWordPress web root
The production WordPress URL is:
The protected NASPO Secure Mail config file must live outside the web root. Production uses:
Managed Paths¶
JoinPPA deploys explicit managed paths rather than synchronizing the full WordPress tree.
Production managed paths currently include:
wp-content/themes/kadencewp-content/themes/joinppa-kadence-childwp-content/plugins/contact-form-7wp-content/plugins/icon-separatorwp-content/plugins/kadence-blockswp-content/plugins/naspo-secure-mailwp-content/plugins/wp-mail-smtpwp-content/plugins/wpremote
Development and staging managed paths currently include the same core theme/plugin set, plus wp-content/plugins/query-monitor. When adding or removing Composer-managed plugins, update the workflow confirm/deploy managed-path arrays for each relevant environment.
Composer-Managed Plugins¶
JoinPPA uses Composer for managed WordPress plugins and themes. The private NASPO Secure Mail package is installed from:
The package requirement is:
Production configures private package authentication during the workflow with the NASPO_SECURE_MAIL_GITHUB_TOKEN GitHub secret.
NASPO Secure Mail¶
JoinPPA uses NASPO Secure Mail plugin version 0.1.0 as the WordPress wp_mail() transport.
The WordPress config boundary is:
The protected config file is stored on the server at:
Required ownership and permissions:
For NASPO Secure Mail, wp-config.php should contain only the NASPO_SECURE_MAIL_CONFIG_FILE pointer, not the mail settings themselves. Site ID, gateway URL, HMAC secret, timeout, and attachment settings belong in the protected config file, not in Git, the WordPress database, or wp-config.php.
Production is configured with the joinppa-prod gateway identity. Policy last verified August 12, 2026:
| Setting | Value |
|---|---|
| Gateway identity | joinppa-prod |
| Environment | prod |
| Status | active |
| Allowed From | info@joinppa.org |
| Default From | info@joinppa.org |
| Delivery mode | send |
| SendGrid sandbox | false |
| Max recipients | 50 |
| Max payload | 10 MiB |
| Rate limit | 60 per minute, 600 per hour |
Do not record HMAC secrets, gateway admin tokens, SendGrid keys, deploy keys, or other secret values in OSKB.
The gateway URL must include the full mail endpoint:
Use the matching environment Worker URL for development and staging:
- Development:
https://naspo-mail-gateway-dev.naspo.workers.dev/v1/mail - Staging:
https://naspo-mail-gateway-staging.naspo.workers.dev/v1/mail - Production:
https://naspo-mail-gateway.naspo.workers.dev/v1/mail
Mail Proof and Safety Model¶
Proof status last verified August 12, 2026:
- Development:
captureverified - Staging:
redirectverified with controlled real delivery to the configured redirect recipient - Production:
sendverified with controlled real delivery through thejoinppa-prodgateway identity
Non-production mail must remain safe:
- Development uses
capture, which validates the signed request without calling SendGrid. - Staging uses
redirect, which calls SendGrid but rewrites all recipients to the server-side configured redirect recipient. - Production uses
sendonly after the staging redirect proof and operator checkpoint.
Production WordPress mail state last verified August 12, 2026:
- NASPO Secure Mail is active.
- WP Mail SMTP is inactive.
- Contact Form 7 From addresses are normalized to
info@joinppa.orgwhere needed. - User-submitted email addresses remain
Reply-Tovalues, notFromvalues.
The main contact form sends to info@joinppa.org, sends from info@joinppa.org, and keeps the submitter's email address as Reply-To. A Leadership Academy or similar request form previously used website@joinppa.org; normalize JoinPPA form From identities to info@joinppa.org unless a different sender is approved in the gateway policy.
Temporary BCC entries used during testing are not permanent mail design. Remove test BCCs after final validation unless Online Services intentionally approves them.
Production validation completed August 12, 2026:
- A controlled
wp_mail()test succeeded throughjoinppa-prodand was received. - A public WordPress account-reset email was requested from the production site and was received from
info@joinppa.org. - The public Contact Form 7 form at
/contact-us/submitted successfully. - Contact Form 7 displayed its successful-send confirmation.
- The resulting contact-form email was received.
JoinPPA production Secure Mail is verified working as of August 12, 2026 for both WordPress transactional mail and Contact Form 7 mail.
WP Mail SMTP is intentionally left installed but inactive as a temporary rollback path during the proof window. Remove WP Mail SMTP from composer.json, composer.lock, and each deployment workflow's managed-path arrays only after NASPO Secure Mail has completed the proof period and rollback is no longer needed.
Rollback¶
During the proof window:
- Deactivate NASPO Secure Mail.
- Reactivate the previous mail transport only with a newly scoped, non-Full-Access credential.
- Do not restore any compromised or deleted SendGrid key.
- Preserve gateway request IDs and WordPress
wp_mail_failedentries for troubleshooting.
For shared mail gateway policy, secrets, revocation, and rotation rules, see Cross-Site Architecture and Deployment.
Documentation to Capture¶
Add validated details about analytics, accessibility, SEO, runbooks, production owner/approver notes, final disposition of the previous joinppa instance, and known issues as they are discovered.