#身份提供者 #令牌 #发行 #本地 #连接 #OIDC #OpenID

app diridp

发行令牌(JWT)为本地文件的OIDC身份提供者

1个不稳定版本

0.1.1 2022年6月10日

#1022密码学

MIT 协议

44KB
910

diridp

Diridp是一个OpenID Connect身份提供者,它将令牌(JWT)作为本地文件系统上的常规文件发行。

diridp生成的令牌通常由同一台机器上的其他进程用于识别自身并连接到第三方服务。因为diridp轮换所有签名密钥和令牌,因此这些可以替换其他永久性凭证。

使用方法

最小配置看起来像

providers:
  main:
    issuer: "https://example.com"
    tokens:
      - path: "/run/diridp/my-application/token"
        claims:
          sub: "my-application"
          aud: "some-cloud-service.example.com"

请参阅配置模板以获取所有可用选项。

Diridp构建时不需要任何网络访问。OpenID Connect文档的提供留给了外部进程,如Nginx或Apache httpd。通常,您会配置一个HTTPS虚拟主机从/var/lib/diridp/<provider>/webroot提供服务。在Nginx中,这可能是这样的

server {
  listen 0.0.0.0:443 ssl;
  server_name example.com;
  ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
  ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;

  # All files in this root are JSON, but may not have the extension.
  root /var/lib/diridp/main/webroot;
  types { }
  default_type application/json;
}

如果您想从同一虚拟主机提供其他内容,您还可以配置需要提供服务的两个特定文件的location

location = /.well-known/openid-configuration {
  root /var/lib/diridp/main/webroot;
  types { }
  default_type application/json;
}

# This path can be customized with the `jwks_path` option in diridp config.
location = /jwks.json {
  root /var/lib/diridp/main/webroot;
  types { }
  default_type application/json;
}

示例:AWS集成

可以在AWS IAM中创建一个身份提供者。这指导AWS如何验证令牌。在Terraform语法中,这可能是这样的

locals {
  example_idp_host = "example.com"
}

resource "aws_iam_openid_connect_provider" "example_idp" {
  # This must match the `issuer` setting in diridp, and virtual host.
  url = "https://${local.example_idp_host}"

  # This must match the `aud` claim in the diridp token.
  client_id_list = ["sts.amazonaws.com"]

  # This pins the certificate authority (CA) that issued the HTTPS certificate,
  # and is required by AWS. Here we determine it at `terraform apply` time, so
  # if the CA certificate ever changes, simply re-apply the Terraform config.
  # This requires the `hashicorp/tls` provider.
  thumbprint_list = [data.tls_certificate.example_idp.certificates[0].sha1_fingerprint]
}

data "tls_certificate" "example_idp" {
  url = "https://${local.example_idp_host}"
}

配置完成后,AWS将在调用STS AssumeRoleWithWebIdentity操作时接受来自此身份提供者的令牌,但我们需要首先创建一个可以使用令牌假设的角色

resource "aws_iam_role" "example_role" {
  name = "example_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = "sts:AssumeRoleWithWebIdentity"
        Principal = {
          Federated = aws_iam_openid_connect_provider.example_idp.arn
        }
        Condition = {
          # This limits the role to tokens with a matching `sub` claim.
          StringLike = {
            "${local.example_idp_host}:sub" = "my-application"
          }
        }
      }
    ]
  })
}

(上面的示例角色没有任何权限。您通常会附加一些策略来允许它真正执行某些操作。)

现在,您可以通过设置以下环境变量在任何使用官方AWS SDK的应用程序中使用该角色

# Matches the `path` in diridp configuration.
AWS_WEB_IDENTITY_TOKEN_FILE="/run/diridp/my-application/token"
# Example, replace with the actual role ARN.
AWS_ROLE_ARN="arn:aws:iam::123456789:role/example_role"

在幕后,AWS SDK执行的操作类似于以下AWS CLI命令

aws sts assume-role-with-web-identity \
  --role-arn "arn:aws:iam::123456789:role/example_role" \
  --role-session-name "<generated by the SDK>" \
  --web-identity-token "<token contents>"

这实际上创建了一个常规的AWS访问密钥,具有非常短的生存期(默认为1小时),然后继续使用该访问密钥正常操作。但是AWS SDK会为您自动刷新。

示例:Docker集成

通过使用带有参数的路径,可以在运行时通过创建目录简单地定义新的令牌

providers:
  main:
    issuer: "https://example.com"
    tokens:
      - path: "/run/diridp/containers/:sub/aws_token"
        claims:
          aud: "sts.amazonaws.com"

Docker会自动为卷挂载创建目录,因此可以使用以下方式启动使用AWS SDK的应用程序

docker run \
  -v /run/diridp/containers/my_app:/run/secrets/diridp:ro \
  -e AWS_WEB_IDENTITY_TOKEN_FILE=/run/secrets/diridp/aws_token \
  -e AWS_ROLE_ARN=arn:aws:iam::123456789:role/example_role \
  my_app:latest

注意,停止/删除容器时,这些目录不会自动清理。

依赖项

~8–20MB
~251K SLoC