Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

14601 authorization api #16495

Merged
merged 40 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d530487
15864 Spring Cloud Gate configuration with Swagger
jalbinson Oct 21, 2024
e68207f
Merge branch 'master' into platform/jamie/15864-spring-cloud-swagger
jalbinson Oct 21, 2024
3403b45
add basic healthcheck test
jalbinson Oct 21, 2024
cbe8404
Merge branch 'platform/jamie/15864-spring-cloud-swagger' of github.co…
jalbinson Oct 21, 2024
8e64119
Merge branch 'master' into platform/jamie/15864-spring-cloud-swagger
jalbinson Oct 21, 2024
74046c6
Merge branch 'master' into platform/jamie/15864-spring-cloud-swagger
jalbinson Oct 22, 2024
9d0dc6f
PR feedback
jalbinson Oct 22, 2024
2986d9c
Merge branch 'master' into platform/jamie/15864-spring-cloud-swagger
jalbinson Oct 22, 2024
652a45e
Merge branch 'platform/jamie/15864-spring-cloud-swagger' of github.co…
jalbinson Oct 22, 2024
a94be0b
config injection cleanup
jalbinson Oct 22, 2024
74a903a
Merge branch 'master' into platform/jamie/15864-spring-cloud-swagger
jalbinson Oct 22, 2024
c093548
fix test
jalbinson Oct 22, 2024
ceea1f7
Merge branch 'platform/jamie/15864-spring-cloud-swagger' of github.co…
jalbinson Oct 22, 2024
df7bac8
14601 authz api
jalbinson Nov 6, 2024
da94858
merge main
jalbinson Nov 6, 2024
c000475
fix merge issue
jalbinson Nov 6, 2024
9ea32e5
comments
jalbinson Nov 6, 2024
c9c2ba7
Merge branch 'main' into platform/jamie/14601-authz-api
emvaldes Nov 7, 2024
e24d2a8
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 7, 2024
6ddc157
doc
jalbinson Nov 7, 2024
77efd61
Merge branch 'platform/jamie/14601-authz-api' of github.com:CDCgov/pr…
jalbinson Nov 7, 2024
75862cc
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 7, 2024
74d025d
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 12, 2024
d290bc7
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 13, 2024
1ace3d1
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 14, 2024
3cb1171
Update auth/docs/setup.md
jalbinson Nov 19, 2024
54fb1ba
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 19, 2024
85abc4a
PR review
jalbinson Nov 19, 2024
a60f074
Merge branch 'platform/jamie/14601-authz-api' of github.com:CDCgov/pr…
jalbinson Nov 19, 2024
f0bf94f
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 21, 2024
dad9f2c
latest version of okta SDK after fix
jalbinson Nov 22, 2024
60f59f7
Merge branch 'platform/jamie/14601-authz-api' of github.com:CDCgov/pr…
jalbinson Nov 22, 2024
6d902c7
revert spring boot update
jalbinson Nov 22, 2024
bd308f4
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Nov 25, 2024
3d6faf3
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Dec 2, 2024
f548a03
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Dec 3, 2024
61b9a8f
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Dec 4, 2024
e5fa576
various changes required for spring boot 3.4.0 on both auth and submi…
jalbinson Dec 4, 2024
494135e
Merge branch 'platform/jamie/14601-authz-api' of github.com:CDCgov/pr…
jalbinson Dec 4, 2024
b1339ae
Merge branch 'main' into platform/jamie/14601-authz-api
jalbinson Dec 5, 2024
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
7 changes: 7 additions & 0 deletions auth/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,18 @@ dependencies {

runtimeOnly("com.nimbusds:oauth2-oidc-sdk:11.19.1")

// okta
// Do not update to 19.0.0 due to breaking issue
// downgraded to 18.0.0 for refresh capability
implementation("com.okta.sdk:okta-sdk-api:18.0.0")
runtimeOnly("com.okta.sdk:okta-sdk-impl:18.0.0")

// Swagger
implementation("org.springdoc:springdoc-openapi-starter-webflux-ui:2.6.0")

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("org.springframework.cloud:spring-cloud-starter-contract-stub-runner")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.4.0")
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ object AuthApplicationConstants {
const val HEALTHCHECK_ENDPOINT_V1 = "/api/v1/healthcheck"
}

/**
* All Submissions service endpoints defined here
*/
object SubmissionsEndpoints {
const val REPORTS_ENDPOINT_V1 = "/api/v1/reports"
object Scopes {
const val ORGANIZATION_SCOPE = "organization"
const val SUBJECT_SCOPE = "sub"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package gov.cdc.prime.reportstream.auth.client

import com.okta.sdk.resource.api.ApplicationGroupsApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.apache.logging.log4j.kotlin.Logging
import org.springframework.stereotype.Service

@Service
class OktaGroupsClient(
private val applicationGroupsApi: ApplicationGroupsApi,
) : Logging {

/**
* Get all application groups from the Okta Admin API
*
* Group names are found at json path "_embedded.group.profile.name"
*
* @see https://developer.okta.com/docs/api/openapi/okta-management/management/tag/ApplicationGroups/#tag/ApplicationGroups/operation/listApplicationGroupAssignments
*/
suspend fun getApplicationGroups(appId: String): List<String> {
return withContext(Dispatchers.IO) {
try {
applicationGroupsApi
.listApplicationGroupAssignments(appId, null, null, null, "group")
.map { it.embedded?.get("group") as Map<*, *> }
.map { it["profile"] as Map<*, *> }
.map { it["name"] as String }
} catch (ex: Exception) {
logger.error("Error retrieving application groups from Okta API", ex)
throw ex
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@ package gov.cdc.prime.reportstream.auth.config

import gov.cdc.prime.reportstream.auth.model.Environment
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.bind.ConstructorBinding
import org.springframework.context.annotation.Bean
import java.time.Clock
import kotlin.time.TimeSource

/**
* Simple class to automatically read configuration from application.yml (or environment variable overrides)
*/
@ConfigurationProperties(prefix = "app")
data class ApplicationConfig @ConstructorBinding constructor(
data class ApplicationConfig(
val environment: Environment,
) {

@Bean
fun timeSource(): TimeSource {
return TimeSource.Monotonic
}

@Bean
fun clock(): Clock {
return Clock.systemUTC()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package gov.cdc.prime.reportstream.auth.config

import com.okta.sdk.client.AuthorizationMode
import com.okta.sdk.client.Clients
import com.okta.sdk.resource.api.ApplicationGroupsApi
import com.okta.sdk.resource.client.ApiClient
import gov.cdc.prime.reportstream.shared.StringUtilities.base64Decode
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class OktaClientConfig(
private val oktaClientProperties: OktaClientProperties,
) {

@Bean
fun apiClient(): ApiClient {
return Clients.builder()
.setOrgUrl(oktaClientProperties.orgUrl)
.setAuthorizationMode(AuthorizationMode.PRIVATE_KEY)
.setClientId(oktaClientProperties.clientId)
.setScopes(oktaClientProperties.requiredScopes)
.setPrivateKey(oktaClientProperties.apiPrivateKey)
// .setCacheManager(...) TODO: investigate caching since groups don't often change
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a ticket for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would just leave this be for now. Caching is something we can worry about if performance becomes a problem especially since this is currently a POC.

.build()
}

@Bean
fun applicationGroupsApi(): ApplicationGroupsApi {
return ApplicationGroupsApi(apiClient())
}

@ConfigurationProperties(prefix = "okta.admin-client")
data class OktaClientProperties(
val orgUrl: String,
val clientId: String,
val requiredScopes: Set<String>,
private val apiEncodedPrivateKey: String,
) {
// PEM encoded format
val apiPrivateKey = apiEncodedPrivateKey.base64Decode()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package gov.cdc.prime.reportstream.auth.filter

import gov.cdc.prime.reportstream.auth.AuthApplicationConstants
import gov.cdc.prime.reportstream.auth.service.OktaGroupsService
import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTConstants
import kotlinx.coroutines.reactor.mono
import org.springframework.cloud.gateway.filter.GatewayFilter
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono

/**
* This filter defines how the Okta-Groups header is added to requests
*/
@Component
class AppendOktaGroupsGatewayFilterFactory(
private val oktaGroupsService: OktaGroupsService,
) : AbstractGatewayFilterFactory<Any>() {

/**
* function used only in testing to create our filter without any configuration
*/
fun apply(): GatewayFilter {
return apply { _: Any? -> }
}

override fun apply(config: Any?): GatewayFilter {
return GatewayFilter { exchange, chain ->
exchange
.getPrincipal<BearerTokenAuthentication>()
.flatMap { oktaAccessTokenJWT ->
val appId = oktaAccessTokenJWT
.tokenAttributes[AuthApplicationConstants.Scopes.SUBJECT_SCOPE] as String
val organizations = oktaAccessTokenJWT
.tokenAttributes[AuthApplicationConstants.Scopes.ORGANIZATION_SCOPE] as List<*>?

// If there is no organization claim present, then we have an application user and
// require appending our custom header
if (organizations == null) {
mono { oktaGroupsService.generateOktaGroupsJWT(appId) }
} else {
Mono.empty()
}
}
.map { oktaGroupsJWT: String ->
exchange.request
.mutate()
.headers {
it.add(OktaGroupsJWTConstants.OKTA_GROUPS_HEADER, oktaGroupsJWT)
}
.build()
}
.switchIfEmpty(Mono.just(exchange.request)) // drop back in original unmodified request if not an app
.flatMap { request ->
chain.filter(exchange.mutate().request(request).build())
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package gov.cdc.prime.reportstream.auth.service

import com.nimbusds.jose.JWSAlgorithm
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.crypto.RSASSASigner
import com.nimbusds.jose.jwk.JWK
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.SignedJWT
import gov.cdc.prime.reportstream.shared.StringUtilities.base64Decode
import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT
import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWTConstants
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.stereotype.Service
import java.time.Clock
import java.time.Duration
import java.util.Date
import java.util.UUID

@Service
class OktaGroupsJWTWriter(
private val jwtConfig: OktaGroupsJWTConfig,
private val clock: Clock,
) {

fun write(model: OktaGroupsJWT): String {
jalbinson marked this conversation as resolved.
Show resolved Hide resolved
val now = clock.instant()
val expires = now.plus(jwtConfig.ttl)
val nbf = now.minus(jwtConfig.nbf)
val claimsSetBuilder = JWTClaimsSet.Builder()
.subject(model.appId)
.issuer(jwtConfig.issuer)
.jwtID(UUID.randomUUID().toString())
.issueTime(Date.from(now))
.notBeforeTime(Date.from(nbf))
.expirationTime(Date.from(expires))
.claim(OktaGroupsJWTConstants.OKTA_GROUPS_JWT_GROUP_CLAIM, model.groups)

val signedJWT = SignedJWT(
JWSHeader.Builder(JWSAlgorithm.RS256).build(),
claimsSetBuilder.build()
)

signedJWT.sign(RSASSASigner(jwtConfig.jwtPrivateKeyJWK.toRSAKey()))

return signedJWT.serialize()
}

/**
* Configuration for Submissions microservice
*/
@ConfigurationProperties(prefix = "okta.jwt")
data class OktaGroupsJWTConfig(
private val jwtEncodedPrivateKeyJWK: String,
val ttl: Duration,
val nbf: Duration,
val issuer: String,
) {
// JWK json format
val jwtPrivateKeyJWK: JWK = JWK.parse(jwtEncodedPrivateKeyJWK.base64Decode())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package gov.cdc.prime.reportstream.auth.service

import gov.cdc.prime.reportstream.auth.client.OktaGroupsClient
import gov.cdc.prime.reportstream.shared.auth.jwt.OktaGroupsJWT
import org.apache.logging.log4j.kotlin.Logging
import org.springframework.stereotype.Service

@Service
class OktaGroupsService(
private val oktaGroupsClient: OktaGroupsClient,
private val oktaGroupsJWTWriter: OktaGroupsJWTWriter,
) : Logging {

suspend fun generateOktaGroupsJWT(appId: String): String {
jalbinson marked this conversation as resolved.
Show resolved Hide resolved
val groups = oktaGroupsClient.getApplicationGroups(appId)
return oktaGroupsJWTWriter.write(OktaGroupsJWT(appId, groups))
}
}
39 changes: 32 additions & 7 deletions auth/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,39 @@ spring:
opaquetoken: # Set client secret in SPRING_SECURITY_OAUTH2_RESOURCESERVER_OPAQUETOKEN_CLIENT_SECRET env variable
client-id: 0oaek8tip2lhrhHce1d7
introspection-uri: https://reportstream.oktapreview.com/oauth2/ausekaai7gUuUtHda1d7/v1/introspect
cloud:
gateway:
routes:
- id: reports_route
uri: http://localhost:8880
predicates:
- Path=/api/v1/reports
filters:
- AppendOktaGroups
- id: health_route
jalbinson marked this conversation as resolved.
Show resolved Hide resolved
uri: http://localhost:8880
predicates:
- Path=/health
filters:
- AppendOktaGroups

server.port: 9000

app:
environment: local

# submissions microservice configuration
submissions:
baseUrl: http://localhost:8080
okta:
adminClient:
orgUrl: https://reportstream.oktapreview.com
clientId: 0oahfz3wazBEHJLEL1d7
requiredScopes:
- okta.apps.read
apiEncodedPrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQ0Njd0dBN0JLUG9oZlQKYmZwdW9vZGFIU3o4VSs2cmVrUEFMdzdNbVJMSHovb3JkZ2pmaWl3RFIzaCtjSkpkVEZBd0NiSFJlVUFpZ0VIYwovZWtMTEpKak1LQUlpM2tJOTJJV0M2bUNRckErRVUweTZsRGpxRGNtZG1Gak9YZUJVUVRtYklzQVROdnU4KzZiCkY0bndWZnE2YTFuUmRuRGJOemNYaE9TbTRlV2JDcmMvUTVIYUZGY2F4S3E5NVRobjBPdXJFbG82TVgwTjJtNUMKT28zTjQvMjArZ21Rc2cyamtiMjdqdGNSVjZIUHBmRFhRZHMwNmZRVzhGZVMxZlIrN1pDOEdzbEIwMjlhL1ZXTAp4QWNIL240cE5FSldSM04vL3JNYys1R2VtOHM2MlJNVEVCbmZBK1BEL01DMWJtN1I0ZVVHTXNKOUgwRHBIY1pMCmtlaWdRZnlaQWdNQkFBRUNnZ0VBQlRGdzRPSUZCeVRMMEFYenowMjNGN1pMb1N2eU4yOWhuUmdDZmRDbU44QW0KMUc0WmdsU3MxZUNWZ21zVzJKSCtLenRua2RCQzVseTJ3b1oxTFpXenFqRTRYYjYzcmN5elllOUs2ejJlYUlvbAp5WjRjWkVQQkZrM21LSjRVRE5qZDJoSitJaC90TFlFV2dhUVpRTEVianlwUTVBN1VCVllZWWw1Ty8vbkVPenpPCmE5cDBhckdIeDRHelBTMnAxeVZhSThQUkMyUnFsNUdnTUxnRlhxTmNZaXpsbmYrNzhLaWtRSzExYkhCTXRCRlUKbzdDWWd5Z0NOQWMxa3lGSXJOSVNxYldFaWJ0OGJYMElVQ2Fpem1RTUtuRG83dXRVbnA0ZTZwU1lQbkU5SVkvdApVdTNKNXVqaktEUDdxUk1wdUNEMDU3WjNHbXI5YWRkcmw0dnFWS2szZFFLQmdRQzMzWVB5YlgzTXRQalRoeXM0CmpWSk5LL2VOTFJ2RjgxTUplS0xIa3VIbkUzSHZzL0ovU2ZVL1U2S2JHT3pOQlBzR3ZwUzZsczMrWUd1TTd4WHYKd3ZZODc0eVBZTS9oRkUrTWhEbVNDZWNmdm1qZTRDU2RBYjFPRWQ5ZHRjYTJHVU5FNEhBRHlVWVRPeWt0c0hndwp4UnZiWDlHZk1ERHdURVhudXVjSDhLcFZ6d0tCZ1FDMW9LZ2xKbGFFelJKUk1QSnE3RlY2WUV4NEo3cVB3aG1GClZJTkNHQUZOSWxhUjRDWG5OYjFma0htM1VkVmdyV3lKby94OCtZSDRweXZWZjNWM0NUWjRhMzdMOVRtQjBTNksKYU9IOFplc295Mi9tOWlqRk9wT3FwQ0ZTaFJmWTUyU29WanVISnFPY0I4aE52Vm1vK1dDVGl5blFzWDhveXE2Mgp1eHEvcVJBSkZ3S0JnUUN4MjlKYm5KYm9ndGVBcDJ5ajAvRWRQYjdHRGpDamwvRm5aQTd5eDU5SERJUld2OWVBClVtYXV6NVNvTzhBMXd1K2hZcEkwdk5TZmtWMzRndjdSWStNV3B4TnRUdFZJZ1lGQ0NGWTRjdVBrelNoZEVLM2EKUTJpQU1NSEZ3S1ZzV1p1ODhPN3FlclVTdlZQa0lxVGhhSXE5OXo2cm9zNTBaUlBxU2Q1YXkrKzUrUUtCZ0d5QgpQZkp6cE54UlpzLzZYZGhpdCs0VCtac09vUFdoRDM0SHJ5S2RGS253Q2FlOE1PaWZ3aktGTFRISFFhSXYrTmVCCmtDVlpLYnhTb20wNWFBTmxEWldESW96V1F6UzZzd01kQldTenZuandrRGw2ZFlEZUxibVR0QlNJVG1iV1ZkdjcKS0RUbGNIaVdiYU9EcXp5M1Btcm1pR1NVcFZMSlF2Y0hjRU52ekpTaEFvR0JBSUxIa2U3aG1Md0JWRDU1SEwzUQpBMDFHUGVWTk9DeCthTlNMMHdTbVlXc3F5MDcvRHAzc3hVVUN0Q1YvN25JY2hnVjFDQTZ4dCs0MkF5VWhzVW9kCmh2MnNQTUw2OFZBSGVSQ3lwTDh5bW5seWZjNmpMS2FqaHBWSmxQcWduSUVNTGZvNXM0UXB1VG9RVUkrZXI3dGIKSTlGRVBGYzlKa21hYWlzcjkxOHNnT0IyCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
jalbinson marked this conversation as resolved.
Show resolved Hide resolved
jwt:
nbf: 5s
ttl: 5m
issuer: http://localhost:9000
jwtEncodedPrivateKeyJWK: eyJwIjoieC1yaFlLVVM2TnpRd0FCYjVmakNEMGl1NlM0MFAySUtQd3pnaUJqU3VjTDZ3VFpoYU4tbTBfZHBEdGhwMHZVQjQyR01LQ2ZHNklWNlFHSV91eF80c3I1QTBRSF9sY09jNC1DbTBWal9Udy1DcFRYbnRaVlJSSDlSN00tdDJ1WXNvT1ZyaXJsUUwxdW1ybThPdjkzVnBUWnJ4QlB6UXBlejZvVGJxZUQ0WF9jIiwia3R5IjoiUlNBIiwicSI6InlYYlhQamJHRmo0cUN3RWJqSUpMQ3hQS1FkTnduX2MtQ0M0ZVBma3UyNTR2VW1jeE1IQ1Q0UGtmQ3ZiTXlKU2plWUxzRFZwY0M1eThqeGJwLXpVMUF3WDJvZk15ZEhJa0RfSW51cjVXM1J2U1ZGUFFqR01YVk5Qc09LU1hxRUUzb3BfSU9QZEtUcXhBR3NZMkhYVEZDYVJSU25SdHMwQnV4ZS10SlZjbnpHcyIsImQiOiJQdmk3YnpOZy1ZekZQcWxsRlNHdXk0UnV5cGE0SDctN1lIZnZEb1pKVktqZFZIcHBqVHNsbjRmZWxicEYxQWJ1c2R2blJnU2QzSHVWQWVTTi1rT2dRbDR6SlNJLThvdDhSd29EQU4wSXNadGg0UDhSbTMwa0JFcFdMR0xPb3Q3ZkFWRDRMSzJFTjVEUlU5dWVVWmNoaFpmcDJwaGl2cHJ4TVluTnlhMzNXSm1oTHdSUFRRVjBIY3JmYk9kVG82a2FHUllfZkpCdHRjd2QzWlQ0dzljOXd6ZzFJT0t6Ul96S2g5VkR1b2Y3SWF0ekNab0ZzeUZ5ZHgwbHZxalZjRXAxSllQMTFBY0VOaUdYOHBSTXpzVktmaUhuNlBET2ZoSXBTU1lBd21wYWI3WGF6V2ZWbEZyam5VQXlpN2wyZV90U1lwMGc1RnpZcjB6NDZrTWo1YnBsIiwiZSI6IkFRQUIiLCJxaSI6IkdWbTR6WllDeTNVNEF6TmhSdE5FWFhzVl9ZYm9CZXR5SS1FRjhhcHNsUGc4YTBhMElzXzFZTTZndTQ4ZlNndVE1WFRpN2RVMURJLTZaR2JSbmVvMXVGb0R1M2RsVGR1dXdrcWx6XzJIREphY1dWZjFWQkRSNkdBSjJ3eWNXckdMM0VkM0k4eGtBeHUzMnlYUGJ0YjlpUy1pRF9WQmo1LVJoSktIUXhHbGNSTSIsImRwIjoid0p5V1JHMEd5UUJteDNZUkZJTVZSWEI3eFFIVktQUW1keFRMQjVVVEFoTFBVWFE1YWJlQm5sdVRCdENQTk1jRjZMTkZQRE1HdTJST290V0dIWjN5R1JTZ2tqN2dwc1J1MWtiTnNvbVNnZk9wcGM5SHpYVnRkUmRPTVdEdVdpYkZfTWJOVkR5eS1zM015LWNJU09kTVBmOHUyUjEzbEVOZ19xUy1sdS1fbllVIiwiZHEiOiJyRXd2MzJ4VzB4VU5QZVlQbW9hZ0NYUS1hVGVjdmFKazhmZ0hNemRXUk1zdmE0a0hmNGI0WWRLTkl3Slp0ejJ2NWE3N2xKdnYxcHFRaE11ekJuM0Z2YlV1N2VpaEFRZlJJYllYRmxYTTBrTUdDY3E0dENmV18xeFRUVW91emQ0ZzU3dEJNTDhGVk8xcDBid3M4ZG80M1hzamJzck9PeHhpNEhPUG9EeS1zOHMiLCJuIjoiblZRNVQ1MFk3Q3NBZkhfWllzQjBhRVFHYnlYcklQdDU1dG5OTGZNSWQwbWJYM1ljdVB6cVVQbVJzYlhiNmNPYmlXT1k1Znk2UGxfaEZDeUs2em9qU1JxaFdCd2dMcHo2NUg3NVJ2bVk5Y2FQbndLSXdPOWhpS2ZHTW5DMkdvS3U2S1otcFFLNXlHaUUwRGhVRGE0Q3gxa0h4NlJUUzVoSXlHZHRFOXk5eGlCU0RJODI0eXVwZ1Z5SkYtU1cteHBINVFYdy1saUxGdVBwSFpnWnQyNEhVRlBPM1JqcXJXTmNkWUZ0S00tZGhzWkxMQXp0cEZSMGlqY3M1SEdjbUVlWnRpaVBJYzFpUF9NWlZGSV9SbnVQdzBxbENFRDF4UGdqeXhzT3ZScDlIdU85NDVfenlib2tyYzlVbTljZnpTTEd3WmdJSW9HZVdtc2VRYWR0Zy1ud1BRIn0=
jalbinson marked this conversation as resolved.
Show resolved Hide resolved

# Ensure these are disabled in production
springdoc:
Expand All @@ -25,7 +49,8 @@ springdoc:
path: /swagger/api-docs

#Uncomment for verbose logging
#logging:
# level:
# web: debug
# org.springframework.web: debug
logging:
jalbinson marked this conversation as resolved.
Show resolved Hide resolved
level:
web: debug
org.springframework.web: debug
com.okta: debug
Loading