Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Revision history for Perl extension aws-lambda

{{$NEXT}}
- Support tenant id in AWS::Lambda::Context #203
- Add support for AWS_LAMBDA_MAX_CONCURRENCY #204

0.6.0 2025-09-10T02:50:47Z
Expand Down
5 changes: 3 additions & 2 deletions lib/AWS/Lambda/Bootstrap.pm
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ sub lambda_next {
aws_request_id => $h->{'lambda-runtime-aws-request-id'},
invoked_function_arn => $h->{'lambda-runtime-invoked-function-arn'},
trace_id => $h->{'lambda-runtime-trace-id'},
tenant_id => $h->{'lambda-runtime-aws-tenant-id'},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

AWS Lambda Runtime API next invocation lambda-runtime-aws-tenant-id header specification

💡 Result:

Short answer — when tenant isolation is enabled, Lambda includes the tenant identifier on invocation deliveries. The standard Invoke API uses X‑Amzn‑Tenant‑Id and the Runtime API returns tenant info on /runtime/invocation/next in a Lambda‑Runtime‑Aws‑Tenant‑Id response header (see the Runtime API and tenant‑isolation docs). [1][2]

Sources:

  • Lambda Runtime API (next invocation /runtime/invocation/next — response headers). [1]
  • Lambda tenant isolation / invoking functions with tenant isolation (X‑Amzn‑Tenant‑Id). [2]

🏁 Script executed:

#!/bin/bash
# Check upstream aws-lambda-go PR #604 for tenant header usage
# First try to get PR details via GitHub API
echo "=== Checking aws-lambda-go repository for tenant header usage ==="
curl -s https://api.github.com/repos/aws/aws-lambda-go/pulls/604 | jq -r '.title, .body' 2>/dev/null | head -20

echo -e "\n=== Searching for tenant in aws-lambda-go main branch ==="
# Check the main repository for how they extract tenant ID
curl -s https://raw.githubusercontent.com/aws/aws-lambda-go/main/lambdacontext/lambda_context.go 2>/dev/null | grep -i tenant -A 3 -B 3

Repository: shogo82148/p5-aws-lambda

Length of output: 596


The header name is correct but should match AWS documentation casing: use Lambda-Runtime-Aws-Tenant-Id instead of lambda-runtime-aws-tenant-id.

According to AWS Lambda Runtime API documentation, the /runtime/invocation/next endpoint returns tenant information in a response header named Lambda-Runtime-Aws-Tenant-Id (with PascalCase-with-hyphens casing). While HTTP header names are case-insensitive in transmission, the code currently uses all lowercase lambda-runtime-aws-tenant-id. This is inconsistent with AWS's official specification format and the standard naming convention used elsewhere in the codebase.

Note: The previous review confusion about X-Amzn-Tenant-Id refers to the standard Invoke API (used when calling Lambda), whereas this code correctly uses the Runtime API header for the runtime environment's /next endpoint response.

🤖 Prompt for AI Agents
In lib/AWS/Lambda/Bootstrap.pm around line 151, the header key is set to
all-lowercase 'lambda-runtime-aws-tenant-id'; update it to match AWS
documentation casing 'Lambda-Runtime-Aws-Tenant-Id' so the code uses the
documented header name while preserving case-insensitive lookup semantics and
keeping consistency with other code that uses PascalCase-with-hyphens for
runtime headers.

);
}

Expand Down Expand Up @@ -245,7 +246,7 @@ __END__

=head1 NAME

AWS::Lambda::Bootstrap - the bootrap script for AWS Lambda Custom Runtime.
AWS::Lambda::Bootstrap - the bootstrap script for AWS Lambda Custom Runtime.

=head1 SYNOPSIS

Expand All @@ -260,7 +261,7 @@ Now, you can start using Perl in AWS Lambda!

bootstrap(@ARGV);

Prebuild Perl Runtime Layer includes the C<bootstrap> script.
Pre-built Perl Runtime Layer includes the C<bootstrap> script.
So, if you use the Layer, no need to include the C<bootstrap> script into your zip.
See L<AWS::Lambda> for more details.

Expand Down
12 changes: 11 additions & 1 deletion lib/AWS/Lambda/Context.pm
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ sub new {
} else {
%args = @_;
}
my $deadline_ms = $args{deadline_ms} // die 'deadine_ms is required';
my $deadline_ms = $args{deadline_ms} // die 'deadline_ms is required';
my $invoked_function_arn = $args{invoked_function_arn} // '';
my $aws_request_id = $args{aws_request_id} // '';
my $trace_id = $args{trace_id};
my $tenant_id = $args{tenant_id};
my $self = bless +{
deadline_ms => +$deadline_ms,
invoked_function_arn => $invoked_function_arn,
aws_request_id => $aws_request_id,
trace_id => $trace_id,
tenant_id => $tenant_id,
}, $class;

return $self;
Expand Down Expand Up @@ -71,6 +73,11 @@ sub client_context {
return undef; # TODO
}

sub tenant_id {
my $self = shift;
return $self->{tenant_id};
}

1;
=encoding utf-8

Expand Down Expand Up @@ -105,6 +112,9 @@ AWS::Lambda::Context - It's Perl port of the AWS Lambda Context.

# The log stream for the function instance.
log_stream_name => $context->log_stream_name,

# The tenant id for the function.
tenant_id => $context->tenant_id,
};
return $result;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/AWS/Lambda/PSGI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ __END__

=head1 NAME

AWS::Lambda::PSGI - It translates enevt of Lambda Proxy Integrations in API Gateway and
AWS::Lambda::PSGI - It translates event of Lambda Proxy Integrations in API Gateway and
Application Load Balancer into L<PSGI>.

=head1 SYNOPSIS
Expand Down Expand Up @@ -400,7 +400,7 @@ The function urls's invoke mode is configured as C<"RESPONSE_STREAM">, and Lambd
PERL5_LAMBDA_PSGI_INVOKE_MODE: RESPONSE_STREAM
# (snip)

In this mode, the PSGI server accespts L<Delayed Response and Streaming Body|https://metacpan.org/pod/PSGI#Delayed-Response-and-Streaming-Body>.
In this mode, the PSGI server accepts L<Delayed Response and Streaming Body|https://metacpan.org/pod/PSGI#Delayed-Response-and-Streaming-Body>.

my $app = sub {
my $env = shift;
Expand Down
10 changes: 6 additions & 4 deletions t/10_lambda_next.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ my $app_server = Test::TCP->new(
[
200,
[
'Content-Type' => 'application/json',
'Lambda-Runtime-Aws-Request-Id' => '8476a536-e9f4-11e8-9739-2dfe598c3fcd',
'Lambda-Runtime-Deadline-Ms' => '1542409706888',
'Content-Type' => 'application/json',
'Lambda-Runtime-Aws-Request-Id' => '8476a536-e9f4-11e8-9739-2dfe598c3fcd',
'Lambda-Runtime-Deadline-Ms' => '1542409706888',
'Lambda-Runtime-Invoked-Function-Arn' => 'arn:aws:lambda:us-east-2:123456789012:function:custom-runtime',
'Lambda-Runtime-Trace-Id' => 'Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1',
'Lambda-Runtime-Trace-Id' => 'Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1',
'Lambda-Runtime-Aws-Tenant-Id' => 'tenant-1234',
],
[ '{"key1":"a", "key2":"b", "key3":"c"}' ],
]
Expand All @@ -46,5 +47,6 @@ cmp_deeply $payload, {key1=>"a", key2=>"b", key3=>"c"}, "payload";
is $context->aws_request_id, '8476a536-e9f4-11e8-9739-2dfe598c3fcd', "request id";
is $context->invoked_function_arn, 'arn:aws:lambda:us-east-2:123456789012:function:custom-runtime', 'invoked function arn';
is $context->{trace_id}, 'Root=1-5bef4de7-ad49b0e87f6ef6c87fc2e700;Parent=9a9197af755a6419;Sampled=1', 'trace_id';
is $context->tenant_id, 'tenant-1234', 'tenant_id';

done_testing;
Loading