Summary
Update EC2 instance-metadata detection and related S3 publishing credential flow to support IMDSv2, which is the default on Amazon Linux 2023+ (and many newer AMIs). Today the CMS probes http://169.254.169.254/latest/meta-data/ with a plain IMDSv1-style GET. On hosts with HttpTokens=required, that probe fails, the product treats the host as non-EC2, and Access Key / Secret remain required even when using Assume Role + role ARN with an instance profile.
Customer / ops impact
- On new AL2023 (and similar) EC2 hosts, Server Properties Configuration for S3 + Assume Role still requires Access Key and Secret.
- Operators cannot rely on instance-profile-only auth unless they temporarily re-enable IMDSv1 (
HttpTokens=optional) or run CMS outside containers without hop-limit issues.
- Docker/container deployments often also need
HttpPutResponseHopLimit >= 2 for IMDSv2; document that alongside the code fix.
Current behavior (root cause)
EC2 detection uses a raw HTTP GET without an IMDSv2 session token:
PSPubServerService.isEC2Instance()
PSAmazonS3DeliveryHandler.isEC2Instance() / getCurrentEc2Region()
UI (PercPublishMinuetView.js) and server validation only skip Access/Secret when isEC2Instance is true. Assume Role alone does not bypass keys.
Runtime path when EC2 is detected correctly:
- Assume Role + EC2 → instance profile credentials call STS AssumeRole(ARN)
- No Assume Role + EC2 → instance profile used for S3
AWS SDK InstanceProfileCredentialsProvider already understands IMDSv2; the custom CMS probe does not.
Proposed work
- Implement IMDSv2-aware metadata client:
PUT /latest/api/token with X-aws-ec2-metadata-token-ttl-seconds
- subsequent GETs with
X-aws-ec2-metadata-token
- short connect/read timeouts
- optional IMDSv1 fallback when v2 is unavailable (for older AMIs)
- Use the same helper for:
isEC2Instance()
getCurrentEc2Region() / AZ → region
- Keep JVM-lifetime cache behavior, but ensure first successful probe works on AL2023 defaults.
- Add unit/integration tests for:
- IMDSv2 success path
- IMDSv2 required / v1 failure path does not false-negative if v2 works
- non-EC2 (timeout/connection refused) remains false
- Docs: note AL2023+, IMDSv2-required, and container hop-limit guidance for S3 publish / Assume Role without static keys.
- (Optional follow-up) Consider DefaultCredentialsProvider / env chain for non-EC2 hosts so ARN-only / IRSA-style setups can work without static keys — out of scope unless agreed.
- Do not make the AWS fields required when S3 is enabled. This would allow the user to work around, Show a non modal warning on save if they are empty, but do not require the fields to be populated.
Acceptance criteria
Related files (expected)
projects/sitemanage/.../PSPubServerService.java (isEC2Instance)
system/business/.../PSAmazonS3DeliveryHandler.java (isEC2Instance, getCurrentEc2Region, assume-role credential build)
PSPubServerRestService /isEC2Instance endpoint
- WebUI:
PercPublishMinuetView.js (consumes isEC2Instance)
- Tests under
PSAmazonS3DeliveryHandlerTest / pub server service tests
Workarounds until fixed
- Temporarily set instance metadata to allow IMDSv1:
HttpTokens=optional
- For containers: increase
HttpPutResponseHopLimit to 2 (still need code fix or IMDSv1 optional for CMS probe)
- Configure static Access Key + Secret (base identity for Assume Role if used)
Cross-repo
Track the same work on both product lines:
intersoftdatalabs-in/percussioncms (Java 17 / mainline)
intersoftdatalabs-in/percussioncms-java8 (Java 8 line)
Co-Authored by Grok Build (TUI) using grok-4.5 with agent main.
Summary
Update EC2 instance-metadata detection and related S3 publishing credential flow to support IMDSv2, which is the default on Amazon Linux 2023+ (and many newer AMIs). Today the CMS probes
http://169.254.169.254/latest/meta-data/with a plain IMDSv1-style GET. On hosts withHttpTokens=required, that probe fails, the product treats the host as non-EC2, and Access Key / Secret remain required even when using Assume Role + role ARN with an instance profile.Customer / ops impact
HttpTokens=optional) or run CMS outside containers without hop-limit issues.HttpPutResponseHopLimit >= 2for IMDSv2; document that alongside the code fix.Current behavior (root cause)
EC2 detection uses a raw HTTP GET without an IMDSv2 session token:
PSPubServerService.isEC2Instance()PSAmazonS3DeliveryHandler.isEC2Instance()/getCurrentEc2Region()UI (
PercPublishMinuetView.js) and server validation only skip Access/Secret whenisEC2Instanceis true. Assume Role alone does not bypass keys.Runtime path when EC2 is detected correctly:
AWS SDK
InstanceProfileCredentialsProvideralready understands IMDSv2; the custom CMS probe does not.Proposed work
PUT /latest/api/tokenwithX-aws-ec2-metadata-token-ttl-secondsX-aws-ec2-metadata-tokenisEC2Instance()getCurrentEc2Region()/ AZ → regionAcceptance criteria
HttpTokens=required, CMS detects EC2 successfully.Related files (expected)
projects/sitemanage/.../PSPubServerService.java(isEC2Instance)system/business/.../PSAmazonS3DeliveryHandler.java(isEC2Instance,getCurrentEc2Region, assume-role credential build)PSPubServerRestService/isEC2InstanceendpointPercPublishMinuetView.js(consumesisEC2Instance)PSAmazonS3DeliveryHandlerTest/ pub server service testsWorkarounds until fixed
HttpTokens=optionalHttpPutResponseHopLimitto2(still need code fix or IMDSv1 optional for CMS probe)Cross-repo
Track the same work on both product lines:
intersoftdatalabs-in/percussioncms(Java 17 / mainline)intersoftdatalabs-in/percussioncms-java8(Java 8 line)