> ## Documentation Index
> Fetch the complete documentation index at: https://developers.authlete.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Handling Certificates

> How to handle certificates from Terraform.

# Certificate handling

Certificates are used in multiple places in OIDC:

* authenticating the server
* authenticating the client
* augmenting a public key with metadata
* establishing trust on a public key

Authorization servers are required to expose and consume certificates to support those use cases, therefore Authlete allows
certificates to be included in different attributes of Service and Client to facilitate implementation of the authorization server.

## Trusted root certificates

The `trusted_root_certificates` property (list of trusted root certificates) of service is a list of the root CA's certificates
in PEM format. The example below shows how you can declare multiple CA certificates using the `local_file` data source:

```shell theme={null}
data "local_file" "ca_ec" {
   filename = "${path.module}/ca_ec.crt"
}

data "local_file" "ca_rsa" {
   filename = "${path.module}/ca_rsa.pem"
}

resource "authlete_service" "as" {
   issuer = "https://${terraform.workspace}.mydomain.com"
   service_name = "My_RSA_AS_${terraform.workspace}"
   description = "A terraform based service for managing the ${terraform.workspace} Authlete based OAuth server"
   supported_grant_types = ["AUTHORIZATION_CODE"]
   supported_response_types = ["CODE"]
   access_token_sign_alg = "RS256"
   access_token_signature_key_id = "rsa1"
   trusted_root_certificates = [ data.local_file.ca_rsa.content, data.local_file.ca_ec.content ]
...
}
```

## JWS and JWE support

The public keys of clients and services can be fetched from PEM certificate files, including or not the chain of certificates.
When loading the public key from X509 certificates, the provider will populate the `x5c`, `x5t`, and `x5t#S256` properties
of JWK.

> If you use a private key PEM file (via the `pem_private_key` property), the public keys will be already available.

If you provide a certificate using RSA or EC key, some JWK attributes will be populated for you. The `kid`, `use`, and
`alg` might be guessed but can't be inferred from the certificate, so you will need to define those attributes.

* In case of RSA public key, the attributes `kty`, `e`, `n`, `x5c`, `x5t`, and `x5t#S256` are populated from the X509 certificate.
* In case of EC public key, the attributes `kty`, `crv`, `x`, `y`, `x5c`, `x5t`, and `x5t#S256` are populated from the certificate.

The declaration of the public keys will be as the examples below:

```shell theme={null}
resource "authlete_service" "as" {
  ...
   jwk {
      kid = "rsa4"
      alg = "RS256"
      use = "sig"
      pem_certificate = file("server_rsa_cert.pem")
      pem_certificate = file("server_rsa_cert.pem")
   }
   ...
   jwk {
      kid = "ec4"
      alg = "ES256"
      use = "sig"
      pem_certificate = file("server_ec_cert.pem")
      pem_private_key = file("server_ec_key.pem")
   }
}
  
resource "authlete_client" "portal" {
...
   jwk {
      kid = "cli1"
      alg = "RS256"
      use = "sig"
      pem_certificate = file("client_rsa_cert.crt")
   }
  
}

resource "authlete_client" "portal2" {
...
   jwk {
      kid = "cli1"
      alg = "ES256"
      use = "sig"
      pem_certificate = file("client_ec_cert.pem")
   }
  
}
```

That will generate JWKs including all the attributes required for representing the public key as below:

Service JWKs:

```json theme={null}
{
  keys: [
    {
        "d": "qEgVnYm62SCf0WYy8Q5SncOCV8Y-aOQ5MbcTwWgh5J5nn3wnTvq_efQiGwXekdcPhiI0oQz_USHEOGwPhiQtY_grhutnzK7wIDvrzrNtDU8jnNXn5XZAbLYinerChICTjGZqdyoHElHPLPpYdAqD2Gxn_0LEw7BRr67_sox2x0W9W3EIzWQhO-1a_Ur3VRTqYfO-dA737cB3cr2Snvbt1Y3AtCxgNahWXlIMH8pzWhnMcImf4Gdr5wGwFvoO2KX3ak7OJd9skAJbsNwrYNaWLc8-DNYl-Dsl-S1jEvz_9V6_X1yxktB_BGKAAm_pm-Szk0esVh0GaX6OwJkxKzOpcQ",
        "e": "AQAB",
        "use": "sig",
        "kid": "rsa2",
        "x5c": [
          "MIIEwTCCAqmgAwIBAgIID+K+XgJff98wDQYJKoZIhvcNAQELBQAwUDELMAkGA1UEBhMCYnIxCzAJBgNVBAgTAkVTMRAwDgYDVQQHEwdWaXRvcmlhMREwDwYDVQQKEwhBdXRobGV0ZTEPMA0GA1UEAwwGcnNhX2NhMB4XDTIyMDcwNjE5NTEwMFoXDTIzMDcwNjE5NTEwMFowUzELMAkGA1UEBhMCYnIxCzAJBgNVBAgTAkVTMRAwDgYDVQQHEwdWaXRvcmlhMREwDwYDVQQKEwhBdXRobGV0ZTESMBAGA1UEAwwJc2VydmVyX29wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA71UPBn2cS7qP89sdIlWEv2KrsTopLuWeIpbzB98V8U1OIvb0YPcCHtpLq+P8u1aceyPotR3AW49BIJ4VzPdTSx+rMmBV0iNv4y289eEZa5Ipvk9TFtEmf7vR6ZMmM1xK7+fcYyf5AIhcZClt5OrFpTboHYadJ5l/rjpRSNxE7i7b34Bi1A/HEgmA3GuPV8yf8nDRwGtzBC+nd5tX7gugDbVw/5fF+HDBGcB4u7Fm6fK6T4C37ohxvI6RWphB3AuEa+UdkR9ceill1Pz0ID+SLdO2Jt+DnxNCNqBa0ezLY70g0no6YkvLcnzbaNh82yE28p1IhweF4CP4b6NyPDIisQIDAQABo4GbMIGYMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFGrTFrTNXRXUDJwCxueMIhznWSw9MAsGA1UdDwQEAwID6DATBgNVHSUEDDAKBggrBgEFBQcDATAUBgNVHREEDTALgglzZXJ2ZXJfb3AwEQYJYIZIAYb4QgEBBAQDAgZAMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBACBKbO/kmaQ2HGxjmy4Vnap5D45ydgOVzFy1juw/QhyyX+Cth71CONt/39tJlE12vJcqcZxV1JMnY3JI5rrX62YxuczCrU5W2+Xn5Jo7lY0mFvGbi89bXQruHIDMnLpyXw4Ri5UkaMTuG/crAj26pMGnCcWFhos7knKQQ4Yu2zwYymhNWlVAbNxTPvM5fcTHSNB2nxU/Q8UqOIzFAKL1iCBPlF3BDaLijQxA6aGYzouiefnzy3ODjOuIy3qM4yfD1gh9jHrRs+h+TJZ3PQ4xZfBkgVMkQcOcsjWEOZf+uXQTVMHF7Y4c41u8VG3IljLCS0ipD86nLq9wbTYRlA3to3IRCj9PwGCZIUALqmmmgRnw834P90mp8GsLtTbVTGO/zLRI46MHeeLiJmeaHVItOpqn5ahpiauqrdXpoGTlecqmfAkyREn64xkTwGqDqL5X0NMIXre+7ydZb56PpZFb8CBviEGmTW6hYvsqHp7E3phPoOs72zww1jTipCC43DrGbYk/FoBjj6SORHpE456Zaj7rboJortVwkI8uwzg799wimTWvz2kGQT4+zDvQMa38XrEuAO8fhqf+2I9QSSLrHMO4MyflFnuLf8KLC3ochRzCJDbkB9K8s/DiELK3pj7NZXwUzT5pxF3n5oZDm/0k4YruLQ7bFY+/xjRBH+741916"
        ],
        "dp": "T8u01EO-rMrx4oR2OnAVg8of6Z-anxFoc_63RGsxlnNvNuKhIbzaxl97MJ5GTKaLWYzQ7Hc_sYOJ2i5-M-eyUYfU3COX4vJ0_H90YJYsemcI1QmaPiQ6da2AZJwXLz_b4x4xTupdOfKpkhiT2yMOvVy8JWGf5GppfWaJ6H43LAE",
        "dq": "XPsQmfFR5VgERHFmzZMz7MOyao0rH6zU9vykvUdj58bdsJ5S_xNrV9QoHhZn9iCVk0TTaIvlWoGrkx9UJ3vnGOL09xklC2hwFTzRC5UhF7mpQaP7Wbl0uKIFS-E-_HH1QLBeOllfidWzq788JsVMSHhyHkAJcNrLTl2a3Pq1Gd0",
        "n": "71UPBn2cS7qP89sdIlWEv2KrsTopLuWeIpbzB98V8U1OIvb0YPcCHtpLq-P8u1aceyPotR3AW49BIJ4VzPdTSx-rMmBV0iNv4y289eEZa5Ipvk9TFtEmf7vR6ZMmM1xK7-fcYyf5AIhcZClt5OrFpTboHYadJ5l_rjpRSNxE7i7b34Bi1A_HEgmA3GuPV8yf8nDRwGtzBC-nd5tX7gugDbVw_5fF-HDBGcB4u7Fm6fK6T4C37ohxvI6RWphB3AuEa-UdkR9ceill1Pz0ID-SLdO2Jt-DnxNCNqBa0ezLY70g0no6YkvLcnzbaNh82yE28p1IhweF4CP4b6NyPDIisQ",
        "p": "_DKf_-iHtdjfYEagYah-RSGgPmntz45QqMelLKwfoA_fVlgADc1jmGxEJj2EewXTwRal1836Lqg9NNgBNvyFcn7kyi2t6GyK2e5uOQTm67Kbmxd_TjQOisPT-gfZbIgJ6c2vLJarHW5EAmWatmgF7l0niETOS_qkDAy7ceDJNm0",
        "kty": "RSA",
        "x5t#S256": "xIFtb8juze-EPXBpJHFIXESG2aSP_lM41iFsz0lQwzo=",
        "q": "8vDHRkSvfaBNsZKk2_EdR_Bljaq24b0ItDcxHwnCSQr3VGo4qIHYsuM_suiJYTgEsX0KwtPgwMNdxYxwYKxDxtNtqk-B0TW64YDLOm6KBAyf8XA0uMedomWm9fkRlP0Bq5I2Q1X8QaiMiFewnex_JTqpGh546SahvOoPJt7nAtU",
        "x5t": "SZQ3eVG5qqIgWYwbb5rzQDEWA4s=",
        "qi": "91xsKekO9sAv2-eKBxUEheHUFHpQz4kmoZY5FpujUYKsSvTQ8OzaZ1S3hoFXwPGd7b6V0oICZhANVTbfPTSq48w63L3MU8x1f4CJjcgaYrH7FR0K3YIaG3818T8971SIzCxhGKVrpnf550XlroXAtq1HaP0tFnO_ggAbOwd1HWY",
        "alg": "RS256"
    },
    {
        "kty": "EC",
        "x5t#S256": "hXIRmXMcBhGWUXT-3jjiu3FsfHtNRzS8zo_yHKeEtNU=",
        "d": "b61zHfrU7_2UzYeKx7xV0fw4rcVLtr80QMlmD3AaayU",
        "use": "sig",
        "x5t": "ce9gSmOTYfOPZQTm9EPLbLjzzMY=",
        "crv": "P-256",
        "kid": "ec2",
        "x5c": [
          "MIICTTCCAdKgAwIBAgIIJWO8OofetF8wCgYIKoZIzj0EAwIwTzELMAkGA1UEBhMCYnIxCzAJBgNVBAgTAmVzMRAwDgYDVQQHEwdWaXRvcmlhMREwDwYDVQQKEwhBdXRobGV0ZTEOMAwGA1UEAwwFZWNfY2EwHhcNMjIwNzA2MTk1NTAwWhcNMjMwNzA2MTk1NTAwWjBPMQswCQYDVQQGEwJCUjELMAkGA1UECBMCRVMxEDAOBgNVBAcTB1ZpdG9yaWExETAPBgNVBAoTCEF1dGhsZXRlMQ4wDAYDVQQDDAVlY19vcDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKR8g0fG81EGXSsU96GDjK8PtWPBPbPb3S3J35X+En7p1RYH8nmzmsJ1wxabpvjYdWR8FI8M3Tm2vfMh3TIu0USjgZcwgZQwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUGI75XaWvWLi6rqx8FYbeiNdhfJswCwYDVR0PBAQDAgPoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBAGA1UdEQQJMAeCBWVjX29wMBEGCWCGSAGG+EIBAQQEAwIGQDAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRlMAoGCCqGSM49BAMCA2kAMGYCMQCLDureFMtAi7YP21tGLOfKDgT5O23lLqgbOWBmhki41Tg0mWDlq/9HrV12Qo07lnoCMQDSeAkpO27p3qqYN18h669COiRfkAxnUXVmc+Ot5yzaMTqjAM2J+JgzNW6sf2sOyYw="
        ],
        "x": "pHyDR8bzUQZdKxT3oYOMrw-1Y8E9s9vdLcnflf4Sfuk",
        "y": "1RYH8nmzmsJ1wxabpvjYdWR8FI8M3Tm2vfMh3TIu0UQ",
        "alg": "ES256"
    }
  ]
}
```

The JWK rendered on client definition on the server side will be as below:

RSA client:

```json lines theme={null}
{
  "keys": [
    {
      "kty": "RSA",
      "x5t#S256": "t-a0q1pOUE1bTh0JtIRKyv4pcRbGP69M2ZJd7hZ5BxE=",
      "e": "AQAB",
      "use": "sig",
      "x5t": "gHwC6AvSUo3_0kdMNePZ3Lln4Ww=",
      "kid": "cli1",
      "x5c": [
        "MIIEqTCCApGgAwIBAgIIMS7U5PYTrDcwDQYJKoZIhvcNAQELBQAwUDELMAkGA1UEBhMCYnIxCzAJBgNVBAgTAkVTMRAwDgYDVQQHEwdWaXRvcmlhMREwDwYDVQQKEwhBdXRobGV0ZTEPMA0GA1UEAwwGcnNhX2NhMB4XDTIyMDcxMTE0MjgwMFoXDTIzMDcxMTE0MjgwMFowUTELMAkGA1UEBhMCYnIxCzAJBgNVBAgTAmVzMRAwDgYDVQQHEwd2aXRvcmlhMREwDwYDVQQKEwhBdXRobGV0ZTEQMA4GA1UEAwwHcnNhX2NsaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL+Mn+vwYxJ6OsiHymHm9WprWamooT3x/qEtx41JQBWYFiEIHJS8fAYQIwqzNlzrn2WJJuH1kdG89hSDi6slSxYCt3ZHwpiNtaD8VqPH1GF0EL31n1IFXKjFECjKUhcvu07ow9WzoJ1ti+G8U/d1edjJOsTgdhrc+ehdhJA0PWUigLfCq639jHkFTAR37B3KXoNqVUROY39gMbx5V/PKCpwh7HoLlyydUnebb0qLtTwWIJgpGCV2vGuNj9CEJpN9NA3xX8pvG3YIZJjuuPCSZWIyps+t2BM+s799emygVu+PUIVG97/2Fh5dhTJ8dJo8eokYIH83tmwNmFCrezFkT4UCAwEAAaOBhTCBgjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRq3YyxPGBl1t94kjg7oBvv+uSCHzALBgNVHQ8EBAMCA7gwEwYDVR0lBAwwCgYIKwYBBQUHAwIwEQYJYIZIAYb4QgEBBAQDAgWgMB4GCWCGSAGG+EIBDQQRFg94Y2EgY2VydGlmaWNhdGUwDQYJKoZIhvcNAQELBQADggIBAIt85Da0F8WvMXiFlaGMew+2vzoXzyZ5GYEvniHPjRIgO9f1urgXEjMKxS1dfn87Zd2TrTTO/UwbkTh6WnMgs5Uuhg9EYeZJ1tbHW3jdrbWOUFzDapImM/JElO4k+Srdcr97m9lN9k8AWPK8IJWGrvvMnwkAQ4rT3gUIUe027CwFw2rL1UsUqpg2ZglzifLm6HcGJoC76eJi86+k+9+9rT02pWPvcvfIq+P3S6ZUjODoIF8OvuLG7SJXlssBMWY5rb/IyGhTvj/1lY0p0A41VbkC4jZLp1Ar69ukorh5Wnzaqtv3HsQ0o+07cxxVCgHdyBXZ5x/1SVPaKvBze2Klwzm+UXwT3miu1HiS26cX6Aa2WymFwtsK1m0NRIUx1H84eT77QvTeDx3IHlQFtOptoC7Mu8UQid7fbCzbk72+eHB5QE2IDAsT3+D/Th76w4fKh2v29/Si+tjT9/MqoQkERxTF/OMvhpriveoJ3p0Oilg15zComFstj6WplC1hjLmLOlaKwsi9BhmqBKTp84hD0GKiDExIezak8Z3yM5cdVi5d+mT+cO495Ispzt9Wgm5WHNldsIG0zsrPFYPC+8YRAw4aDMVqDj6RpB0quijhchyPp6ZcTENi9zQx9Bz8oIZwSTQOly8xxz04an4K/8pMGaVfBsSW7EQoueiR+69mucah"
      ],
      "alg": "RS256",
      "n": "v4yf6_BjEno6yIfKYeb1amtZqaihPfH-oS3HjUlAFZgWIQgclLx8BhAjCrM2XOufZYkm4fWR0bz2FIOLqyVLFgK3dkfCmI21oPxWo8fUYXQQvfWfUgVcqMUQKMpSFy-7TujD1bOgnW2L4bxT93V52Mk6xOB2Gtz56F2EkDQ9ZSKAt8Krrf2MeQVMBHfsHcpeg2pVRE5jf2AxvHlX88oKnCHseguXLJ1Sd5tvSou1PBYgmCkYJXa8a42P0IQmk300DfFfym8bdghkmO648JJlYjKmz63YEz6zv316bKBW749QhUb3v_YWHl2FMnx0mjx6iRggfze2bA2YUKt7MWRPhQ"
    }
  ]
}
```

EC client:

```json lines theme={null}
{
  "keys": [
    {
      "kty": "EC",
      "x5t#S256": "ry5BGq-8SjFGW7qF5CaND5nbfAQtSV8bc07Dw2ajS_k=",
      "use": "sig",
      "x5t": "fyitL1mLbo4qinKoNwSCTDUlkNg=",
      "crv": "P-256",
      "kid": "cli1",
      "x5c": [
        "MIICOzCCAcGgAwIBAgIIWCYugLSRzh0wCgYIKoZIzj0EAwIwTzELMAkGA1UEBhMCYnIxCzAJBgNVBAgTAmVzMRAwDgYDVQQHEwdWaXRvcmlhMREwDwYDVQQKEwhBdXRobGV0ZTEOMAwGA1UEAwwFZWNfY2EwHhcNMjIwNzExMTQyOTAwWhcNMjMwNzExMTQyOTAwWjBQMQswCQYDVQQGEwJicjELMAkGA1UECBMCZXMxEDAOBgNVBAcTB3ZpdG9yaWExETAPBgNVBAoTCEF1dGhsZXRlMQ8wDQYDVQQDDAZlY19jbGkwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQHTsEYCM0XqXsO6H1XRHeAZ8vsuJA4PM8JKDU+LH5Pep44CDSysTD+7206awaJEDF0f+HkRU1EOMNWYnNQBaSHo4GFMIGCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBlcinWHTKgZoD9oqnuzy8jALs40MAsGA1UdDwQEAwIDuDATBgNVHSUEDDAKBggrBgEFBQcDAjARBglghkgBhvhCAQEEBAMCBaAwHgYJYIZIAYb4QgENBBEWD3hjYSBjZXJ0aWZpY2F0ZTAKBggqhkjOPQQDAgNoADBlAjBExTk22WfzyyseoV78KLZ5QYK9OdMRTxLgXg85sGQok0lsQjnfITXuq08CjXTJfboCMQChAvVvOeDBvMM1572oPEo1PtuF5geFViYWxt2chWb2/FjoiKjJFn3Y1sC1onxs2W0="
      ],
      "x": "B07BGAjNF6l7Duh9V0R3gGfL7LiQODzPCSg1Pix-T3o",
      "y": "njgINLKxMP7vbTprBokQMXR_4eRFTUQ4w1Zic1AFpIc",
      "alg": "ES256"
    }
  ]
}
```
