You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Serverless部署后AWS Access Key无效问题求助

Serverless + Lambda 使用S3时 InvalidAccessKeyId 错误排查

我是Serverless和Lambda新手,应用中需要用到S3服务。用自己AWS账户手动创建的凭证能正常访问S3,但通过Serverless部署后,无论是线上还是本地运行,都报错:InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.

serverless.yaml

org: juan
app: knot
service: knot-be
provider:
  environment:
    APP_ENV: staging
    ...... env variables.....
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  apiGateway:
    binaryMediaTypes:
      - "*/*"
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:*"
      Resource: "arn:aws:s3:::knot-be/*"
    - Effect: "Allow"
      Action:
        - "ses:SendEmail"
        - "ses:SendRawEmail"
      Resource: "*"
    - Effect: "Allow"
      Action:
        - "rds:*"
      Resource: "*"
  ecr:
    images:
      appimage:
        path: ./
functions:
  api:
    image:
      name: appimage
      command: 
        - dist/lambda.handler
      entryPoint:
        - '/lambda-entrypoint.sh'
    timeout: 30    
    events:
      - http:
          path: /{proxy+}
          method: any
      - http:
          path: /
          method: any
resources:
  Resources:
    Bloodknot3Bucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: knot-be

plugins:
  - serverless-offline

s3.config.ts

const s3Config = {
  bucketName: process.env.AWS_S3_BUCKET_NAME || 'bloodknot-storage-dev',
  region: (process.env.AWS_REGION || 'us-east-2') as BucketLocationConstraint,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID || '',
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || '',
  },
}

const s3Client = new S3Client(s3Config)


export {
  s3Config,
  GetObjectCommand,
  PutObjectCommand,
  DeleteObjectCommand,
  ListObjectsV2Command,
  S3Client,
  getSignedUrl,
}

export default s3Client

我创建了端点检查环境变量,部署后返回的结果显示变量存在:

{ "bucketName": "knot-be", "region": "us-east-1", "credentials": { "accessKeyId": "ASIA.....", "secretAccessKey": "qG....." } }

但无论线上还是本地运行,都会触发以下错误:

[Nest] 5538  - 05/07/2024, 1:00:21 AM   ERROR [S3StorageProvider] InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.
[Nest] 5538  - 05/07/2024, 1:00:21 AM   ERROR [ExceptionsHandler] Error uploading file at 6b613615-af7b-4408-8566-89e9a5f08872
Error: Error uploading file at 6b613615-af7b-4408-8566-89e9a5f08872
    at S3StorageProvider.uploadFile (/home/seb/Desktop/knotblood/bloodknot-backend/src/commons/providers/file-storage/s3/s3-storage.provider.ts:125:13)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.all (index 0)

为什么本地用自己的AWS凭证能正常工作,但用Serverless提供的变量时,无论线上还是本地都报错?是serverless.yaml配置有误,还是需要在AWS后台做额外配置?


解决方案
  • 移除硬编码凭证,让AWS SDK自动使用IAM角色
    Lambda运行时会自动获取执行角色的临时凭证,不需要在代码里显式传入credentials参数。你已经在serverless.yaml中配置了iamRoleStatements,给Lambda赋予了S3访问权限,直接修改s3.config.ts:

    const s3Config = {
      bucketName: process.env.AWS_S3_BUCKET_NAME || 'bloodknot-storage-dev',
      region: (process.env.AWS_REGION || 'us-east-2') as BucketLocationConstraint,
      // 移除credentials配置,SDK会自动使用Lambda执行角色
    }
    

    你看到的ASIA开头的是临时会话凭证,这类凭证需要搭配sessionToken才能生效,但你只传入了accessKeyId和secretAccessKey,导致验证失败。

  • 检查serverless.yaml的环境变量配置
    确认environment字段中是否误写入了临时凭证。Serverless部署Lambda时不需要手动注入AWS凭证,Lambda会通过IAM角色获取权限,所以要确保AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY没有被错误设置。

  • 本地运行serverless-offline的配置
    本地运行时,serverless-offline会读取你本地的AWS配置(~/.aws/credentials或本地环境变量),不需要在代码里硬编码。确保本地的AWS凭证有对应S3桶的访问权限,同时代码不传入credentials,让SDK自动读取本地配置。

  • 修正S3权限的Resource范围
    当前IAM权限只允许访问桶内对象(arn:aws:s3:::knot-be/*),如果代码涉及桶级操作(比如获取桶信息),需要补充桶本身的权限:

    - Effect: "Allow"
      Action:
        - "s3:*"
      Resource: 
        - "arn:aws:s3:::knot-be"
        - "arn:aws:s3:::knot-be/*"
    

内容的提问来源于stack exchange,提问作者Sebastian Rodriguez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:47:04