terraform-provider-okta icon indicating copy to clipboard operation
terraform-provider-okta copied to clipboard

Support generating private keys for okta_app_oauth resources

Open simondemartini opened this issue 2 years ago • 3 comments

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

It would be helpful to have a way to easily generate a full JWK so that a newly-created okta_app_oauth app can use the private_key_jwt token endpoint auth method without manual steps. For example, a user could create the app, the private keys and JWKS, then store all the secrets in another provider's secret manager all with one terraform command.

okta_app_oauth currently allows a user to set a public JWKS, but it's very tedious to generate the private key for that JWKS. The current recommended manual process recommended in other issues suggests using a couple of different random sites and tools to do this which isn't ideal imo.

It would be great if the okta terraform had some native functions, APIs, or tools to generate/assign these JWKS out of the box.

New or Affected Resource(s)

  • okta_app_oauth

References

  • #1035
  • #657
  • #152

simondemartini avatar Aug 12 '22 02:08 simondemartini

@simondemartini , agreed, your write up reminds me of when I first on-boarded at Okta I was shown how to roll JSKS and private keys by hand. I'll have to look into this further. /cc @duytiennguyen-okta

monde avatar Aug 15 '22 15:08 monde

Okta internal reference: https://oktainc.atlassian.net/browse/OKTA-524182

monde avatar Aug 15 '22 15:08 monde

The current recommended manual process https://github.com/okta/terraform-provider-okta/issues/1035 suggests using a couple of different random sites and tools to do this which isn't ideal imo.

Huge +1 on this. The suggestion to send a private key to a 3rd party is not good for security. https://github.com/jpf/lokey/ can covert jwk to pem locally, but it requires python2.6. Regardless, manual handling of private keys is a security risk and automation is the best way to avoid it.

antonmos avatar Aug 22 '22 18:08 antonmos

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days

github-actions[bot] avatar Oct 22 '22 00:10 github-actions[bot]

This is still an issue that would be great to have addressed!

la-palma avatar Oct 24 '22 16:10 la-palma

I'm looking at this now in my current sprint

monde avatar Oct 24 '22 16:10 monde

Was just re-reading through the description of this issue @simondemartini . I just wanted to say I take exception with this characterization: The current recommended manual process ... suggests using a couple of different random sites and tools to do this which isn't ideal imo.. One can never know what operating system a user is making use of, what tool chain they have access to, or what their level of experience is. So showing examples with mkjwk.org is clearly for illustrative purposes. We've considered going back and editing any comment that makes reference to mkjwk.org and add an editorial note like "don't do this in production, this is an example". But doing so, imo, would be restating the obvious.

monde avatar Oct 31 '22 21:10 monde

Note to self: see if any of this work can help resolve #1330

monde avatar Nov 01 '22 16:11 monde

@simondemartini @antonmos @la-palma I wrote a config that makes use of a couple of other providers to illustrate how you could use TF to generate a PEM value, that you would perhaps save in a secrets manager (but not save in a TF state file). Use the PEM to create a JWKS that can be used when creating an Okta OAuth app.

As you all have reminded the community - practice good security, whether a secret is generated with trusted software like openssl, the Hashicorp TLS provider, or some random internet site ... make sure to audit their code before trusting it in production.

# This example config illustrates how Terraform can be used to generate a
# private keys PEM file and valid JWKS to be used as part of an Okta OAuth
# app's creation.
#
terraform {
  required_providers {
    okta = {
      source = "okta/okta"
    }
    tls = {
      source = "hashicorp/tls"
    }
    jwks = {
      source = "iwarapter/jwks"
    }
  }
}

# NOTE: Example to generate a PEM easily as a tool. These secrets will be saved
# to the state file and shouldn't be persisted. Instead, save the secrets into
# a secrets manager to be reused.
# https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key
#
# NOTE: Even though tls is a Hashicorp provider you should still audit its code
# to be satisfied with its security.
# https://github.com/hashicorp/terraform-provider-tls
#
resource "tls_private_key" "rsa" {
  algorithm = "RSA"
  rsa_bits  = 4096
}
#
# Pretty print a PEM with TF show and jq
# terraform show -json | jq -r '.values.root_module.resources[] | select(.address == "tls_private_key.rsa").values.private_key_pem'
#
# Delete the secrets explicitly or just remove them from the config and run
# apply again.
# terraform apply -destroy -auto-approve -target=tls_private_key.rsa

# NOTE: Even though the iwarapter/jwks is listed in the registry you should
# still audit its code to be satisfied with its security.
# https://registry.terraform.io/providers/iwarapter/jwks/latest/docs/data-sources/from_key
# https://github.com/iwarapter/terraform-provider-jwks
#
data "jwks_from_key" "jwks" {
  key = tls_private_key.rsa.private_key_pem
  kid = "my-kid"
}
#
# Pretty print the jwks
# terraform show -json | jq -r '.values.root_module.resources[] | select(.address == "data.jwks_from_key.jwks").values.jwks' | jq .

# Feed values into Okta OAuth app's jwks
locals {
  jwks = jsondecode(data.jwks_from_key.jwks.jwks)
}

# https://registry.terraform.io/providers/okta/okta/latest/docs/resources/app_oauth
resource "okta_app_oauth" "app" {
  label                      = "My OAuth App"
  type                       = "service"
  response_types             = ["token"]
  grant_types                = ["client_credentials"]
  token_endpoint_auth_method = "private_key_jwt"

  jwks {
    kty = local.jwks.kty
    kid = local.jwks.kid
    e   = local.jwks.e
    n   = local.jwks.n
  }
}
#
# Pretty print OAuth app Client ID
# terraform show -json | jq -r '.values.root_module.resources[] | select(.address == "okta_app_oauth.app").values.id'

monde avatar Nov 02 '22 20:11 monde