npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pixlcore/xyplug-sso-aws-alb

v1.0.0

Published

A xyOps SSO Plugin for authenticating users via AWS ALB OIDC.

Readme

xyOps AWS ALB SSO Plugin

xyplug-sso-aws-alb is a custom SSO command plugin for xyOps.

It is designed for AWS Application Load Balancers that use native OIDC authentication at the listener layer. The plugin reads the ALB headers that AWS forwards to your backend, validates the ALB-signed JWT, extracts user claims, and emits standard trusted headers back to xyOps.

Please read the xyOps SSO documentation before proceeding.

What it does

The plugin reads these incoming AWS ALB headers from the xyOps SSO command request:

  • x-amzn-oidc-identity
  • x-amzn-oidc-data

It then:

  1. Verifies the JWT from x-amzn-oidc-data using aws-jwt-verify.
  2. Validates the ALB signer ARN, issuer, and client ID.
  3. Extracts identity and claims from the verified payload.
  4. Emits headers that match your xyOps header_map, such as:
    • x-forwarded-user
    • x-forwarded-name
    • x-forwarded-email
    • x-forwarded-groups

xyOps then continues through its normal SSO flow as if those trusted headers had been forwarded by a traditional auth proxy.

Requirements

  • Node.js 18 or higher
  • npx available on the xyOps conductor
  • xyOps with SSO custom command support (v1.0.40+)
  • An AWS ALB listener already configured for OIDC authentication
  • Network egress from the xyOps conductor to the AWS ALB public key endpoint on the first verification of each new token or key ID

Install and run

The plugin is designed to be invoked by xyOps itself through sso.json.

Recommended command:

"command": "npx -y @pixlcore/[email protected]"

If you prefer, you can also preinstall the package and execute it directly:

"command": "xyplug-sso-aws-alb"

That works if the executable is already on your server PATH.

How xyOps calls the plugin

xyOps launches the command before its normal SSO header processing. It sends a one-line JSON document to STDIN containing:

  • the full SSO config object
  • the request headers
  • parsed cookies
  • request IP metadata

The plugin must return a one-line JSON document on STDOUT using the xyOps wire protocol:

{
	"xy": 1,
	"code": 0,
	"headers": {
		"x-forwarded-user": "[email protected]",
		"x-forwarded-name": "Example User",
		"x-forwarded-email": "[email protected]",
		"x-forwarded-groups": "admins,operators"
	}
}

Important:

  • Logical auth failures are returned with code: 1 in JSON.
  • The plugin is intentionally written to emit JSON and exit normally, so xyOps can display a meaningful SSO error.

Recommended xyOps configuration

Edit /opt/xyops/conf/sso.json and configure SSO like this:

{
	"enabled": true,
	"whitelist": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
	"header_map": {
		"username": "x-forwarded-user",
		"full_name": "x-forwarded-name",
		"email": "x-forwarded-email",
		"groups": "x-forwarded-groups"
	},
	"cleanup_username": false,
	"cleanup_full_name": false,
	"group_role_map": {},
	"group_privilege_map": {},
	"command": "npx -y @pixlcore/[email protected]",
	"jwt": {
		"provider": "aws_alb",
		"header": "x-amzn-oidc-data",
		"claim_map": {
			"username": "email",
			"email": "email",
			"full_name": "name",
			"groups": "groups"
		},
		"aws_alb": {
			"alb_arn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/example/abc123",
			"issuer": "https://accounts.google.com",
			"client_id": "your-oidc-client-id",
			"grace_seconds": 0
		}
	}
}

This works because:

  • xyOps only cares about the standard trusted headers in header_map
  • xyOps ignores the custom jwt block
  • the plugin reads jwt from the command input, verifies the AWS token, and prints matching headers back out

Header map recommendations

Recommended header map:

"header_map": {
	"username": "x-forwarded-user",
	"full_name": "x-forwarded-name",
	"email": "x-forwarded-email",
	"groups": "x-forwarded-groups"
}

Using distinct headers is the cleanest configuration.

You can map multiple xyOps fields to the same header name if you want, for example:

"header_map": {
	"username": "x-forwarded-user",
	"full_name": "x-forwarded-user",
	"email": "x-forwarded-email",
	"groups": "x-forwarded-groups"
}

In that case, the plugin emits only one value for the shared header name. This is useful when you want xyOps to derive a prettier full name using cleanup_full_name.

Recommendation:

  • Use distinct headers if you want the plugin to pass a real full name.
  • Reuse the username header only if you intentionally want xyOps to derive the display name itself.

AWS JWT configuration

The plugin expects a jwt object in sso.json.

jwt.provider

Set this to:

"provider": "aws_alb"

jwt.header

This is the incoming request header that contains the ALB JWT.

For AWS ALB, use:

"header": "x-amzn-oidc-data"

jwt.claim_map

This tells the plugin which verified claims to use for xyOps fields.

Example:

"claim_map": {
	"email": "email",
	"full_name": "name",
	"groups": "groups"
}

Each value may be:

  • a string claim name such as "email"
  • a dotted path such as "custom.profile.name"
  • an array of fallbacks such as ["name", "preferred_username", "email"]

Common mappings:

  • username: often email or preferred_username
  • email: usually email
  • full_name: usually name
  • groups: depends on your IdP, often groups, roles, or a custom claim

jwt.aws_alb.alb_arn

This must match the AWS ALB signer ARN.

Example:

"alb_arn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/example/abc123"

You may also provide an array if you trust multiple ALBs for the same issuer:

"alb_arn": [
	"arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/alb-a/abc123",
	"arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/alb-b/def456"
]

jwt.aws_alb.issuer

This must match the JWT iss claim from your OIDC provider.

Examples:

  • https://accounts.google.com
  • https://YOUR_OKTA_DOMAIN/oauth2/default
  • https://cognito-idp.us-west-2.amazonaws.com/us-west-2_ABC123

jwt.aws_alb.client_id

This must match the ALB JWT client identifier.

Example:

"client_id": "your-oidc-client-id"

You may also set it to null if you intentionally want to skip client validation, but that is not recommended.

jwt.aws_alb.grace_seconds

Optional clock-skew allowance in seconds.

Example:

"grace_seconds": 30

Optional advanced settings

The plugin also understands these optional properties:

"jwt": {
	"cache_dir": "/tmp/xyplug-sso-aws-alb-cache",
	"aws_alb": {
		"jwks_uri": "https://public-keys.auth.elb.us-west-2.amazonaws.com"
	}
}

Notes:

  • cache_dir overrides the default on-disk token cache path.
  • jwks_uri is mainly useful for advanced testing. In normal AWS setups you should omit it and let aws-jwt-verify derive the correct ALB public key endpoint from the ALB ARN region.

Username, email, and full name behavior

The plugin resolves values in this general order:

Username

Preferred sources:

  1. claim_map.username
  2. common fallback claims such as preferred_username, username, email
  3. x-amzn-oidc-identity
  4. JWT sub

Note:

  • AWS ALB sets x-amzn-oidc-identity to the OIDC sub claim.
  • In many environments that is a stable opaque identifier rather than a friendly username.
  • For that reason, the plugin prefers mapped claims first and uses the ALB identity header as a fallback.

Email

Preferred sources:

  1. claim_map.email
  2. common email claim
  3. username fallback

This fallback exists because current xyOps SSO requires both username and email to be present.

Recommendation:

  • Make sure your IdP returns a real email claim if you want a proper user email in xyOps.

Full name

Preferred sources:

  1. claim_map.full_name
  2. common name claim
  3. given_name + family_name
  4. email
  5. username

If your IdP does not provide a full name, that is fine. You can:

  • map full_name to its own header and let the plugin fall back automatically
  • or map full_name to the same header as username or email and let xyOps derive a prettier display name via cleanup_full_name

Groups, roles, and privileges

The plugin returns groups as a single trusted header, usually x-forwarded-groups.

xyOps then consumes that header through its normal SSO settings:

  • group_role_map
  • group_privilege_map
  • group_role_separator
  • replace_roles
  • replace_privileges

Example:

"header_map": {
	"groups": "x-forwarded-groups"
},
"group_role_map": {
	"devops": ["r12345"],
	"oncall": ["r67890"]
},
"group_privilege_map": {
	"platform-admins": ["admin"],
	"ticket-managers": ["edit_tickets", "delete_tickets"]
}

If the verified JWT contains:

{
	"groups": ["devops", "platform-admins"]
}

The plugin will emit:

"x-forwarded-groups": "devops,platform-admins"

Then xyOps will:

  • add role r12345
  • grant the admin privilege

Group separator

If your group claim is an array, the plugin joins it using your xyOps group_role_separator.

Example:

"group_role_separator": "|"

In that case the plugin will emit:

"x-forwarded-groups": "devops|platform-admins"

If your JWT claim is already a string, the plugin passes it through as-is. So if your IdP returns a string, make sure its delimiter matches the separator you configured in xyOps.

Performance and caching

To keep things fast, the plugin maintains a small on-disk cache keyed by:

  • the raw ALB JWT
  • the relevant SSO config

Default cache path:

/tmp/xyplug-sso-aws-alb-cache

The cache stores only:

  • the verified token expiration time
  • the generated trusted headers

The cache expires automatically when the JWT expires.

Security notes

  • The plugin validates the ALB JWT signature with aws-jwt-verify.
  • The plugin validates the ALB signer ARN.
  • The plugin validates the issuer.
  • The plugin validates the client ID unless you explicitly disable that by setting client_id to null.
  • If both x-amzn-oidc-identity and JWT sub are present, the plugin checks that they match.
  • The plugin does not perform IP/CIDR validation. xyOps still does that via SSO.whitelist.

Infrastructure recommendations:

  • Restrict your xyOps target so only the ALB can reach it.
  • Keep SSO.whitelist enabled.
  • Use HTTPS end-to-end where possible.

What this plugin does not do

  • It does not replace xyOps SSO user creation, session creation, or group mapping.
  • It does not manage logout behavior for AWS ALB auth cookies.
  • It does not validate source IPs. xyOps still does that.
  • It does not mutate any xyOps config on disk.

Troubleshooting

Login fails with a JWT verification error

Check:

  • jwt.aws_alb.alb_arn
  • jwt.aws_alb.issuer
  • jwt.aws_alb.client_id
  • network access to the AWS ALB public key endpoint

Groups are missing

Check:

  • that your IdP is actually returning the group claim
  • the jwt.claim_map.groups value
  • your xyOps group_role_separator

Usernames look strange

Remember that xyOps has its own username normalization rules.

If your OIDC sub contains characters outside the xyOps username character set, xyOps may normalize them. If you prefer friendlier usernames, map username to another claim that is stable in your environment.

Need more debugging output

On the xyOps side:

  • set debug_level to 9
  • inspect logs/SSO.log

On the plugin side:

  • set XYP_SSO_DEBUG=1 in the environment for the xyOps service to have the plugin write extra diagnostic information to STDERR

xyOps logs raw plugin STDOUT and STDERR at SSO debug level 9.

Local development

To syntax-check the CLI:

npm test

To run it manually with a saved JSON input:

cat sample-input.json | node index.js

The plugin expects the same XYWP payload that xyOps sends to custom SSO commands.