mTLS on Service Callout with Dynamic URL

VAP
Bronze 4
Bronze 4

Hi Apigee experts,

We have a scenario where we use a ServiceCallout on which URL and Path of the target are set dynamically at runtime through variables. In this scenario where the target endpoint changes at runtime, is it possible to have mTLS (Apigee to send client certificate to the different targets)?

We can pre-provision each client certificate (for each target service), but I'm not sure if at runtime Apigee is able to select the correct client certificate to send to the target.

Thanks,

V

 

Solved Solved
0 2 365
1 ACCEPTED SOLUTION

The SSLInfo configuration block that is available inside ServiceCallout accepts message templates, which means you can tell Apigee to select the keystore and truststore dynamically.  You would need logic inside the API proxy to set variables referring to the designed keystore and truststore and keyalias, based on the endpoint the ServiceCallout is connecting to.  There is no configuration possibility to tell Apigee to automatically or implicitly "look up" the keystore and truststore based on the target URL in the ServiceCallout policy.  But you can do that work yourself in the API proxy.  

One way I can think of to do that is to have a .properties file embedded within the API proxy, and then a JavaScript or AssignMessage policy that does the "lookup" of the keystore, keyalias, and truststore based on the target. (BTW, properties files work only with hybrid and X.  Not with Apigee Edge). The properties file might look like this: 

 

 

# myprops.properties

targ1_url = https://foo.bar
targ1_keyalias = key1
targ1_keystore = keystore1
targ1_truststore = truststore1

targ2_url = https://example.com
targ2_keyalias = key2
targ2_keystore = keystore2
targ2_truststore = truststore2

#... and so on

 

 

And then at some point in the logic within the context of a Request, the proxy selects either targ1 or targ2.  At that point you can do this with AssignMessage

 

 

<AssignMessage name='AM-Get-SSLInfo-Settings'>
  <!-- get the variables holding the names of properties that we want to retrieve -->
  <AssignVariable> 
    <Name>var-for-url</Name> 
    <Template>propertyset.myprops.{selected-target}_url</Template>
  </AssignVariable>
  <AssignVariable> 
    <Name>var-for-keyalias</Name> 
    <Template>propertyset.myprops.{selected-target}_keyalias</Template>
  </AssignVariable>
  <AssignVariable> 
    <Name>var-for-keystore</Name> 
    <Template>propertyset.myprops.{selected-target}_keystore</Template>
  </AssignVariable>
  <AssignVariable> 
    <Name>var-for-truststore</Name> 
    <Template>propertyset.myprops.{selected-target}_truststore</Template>
  </AssignVariable>

  <!-- now set the dynamic URL for the ServiceCallout -->
  <AssignVariable> 
    <Name>servicecallout.SC-dynamic.target.url</Name> 
    <Template ref='var-for-url'/>
  </AssignVariable>
</AssignMessage>

 

 

And then in ServiceCallout

 

 

<ServiceCallout name='SC-dynamic'>
  ...
  <HTTPTargetConnection>
    <Properties/>
    <URL>https://this-will-be-overwritten.com</URL>
    <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>{var-for-keystore}</KeyStore>
        <KeyAlias>{var-for-keyalias}</KeyAlias>
        <TrustStore>{var-for-truststore}</TrustStore>
        <IgnoreValidationErrors>false</IgnoreValidationErrors>
    </SSLInfo>
  </HTTPTargetConnection>
</ServiceCallout>

 

 

 You could do something similar with a .json file and a JavaScript to select/set variables. You could use the KVM to store these settings, too.  Lots of options, but the pattern is pretty similar.

 

View solution in original post

2 REPLIES 2

The SSLInfo configuration block that is available inside ServiceCallout accepts message templates, which means you can tell Apigee to select the keystore and truststore dynamically.  You would need logic inside the API proxy to set variables referring to the designed keystore and truststore and keyalias, based on the endpoint the ServiceCallout is connecting to.  There is no configuration possibility to tell Apigee to automatically or implicitly "look up" the keystore and truststore based on the target URL in the ServiceCallout policy.  But you can do that work yourself in the API proxy.  

One way I can think of to do that is to have a .properties file embedded within the API proxy, and then a JavaScript or AssignMessage policy that does the "lookup" of the keystore, keyalias, and truststore based on the target. (BTW, properties files work only with hybrid and X.  Not with Apigee Edge). The properties file might look like this: 

 

 

# myprops.properties

targ1_url = https://foo.bar
targ1_keyalias = key1
targ1_keystore = keystore1
targ1_truststore = truststore1

targ2_url = https://example.com
targ2_keyalias = key2
targ2_keystore = keystore2
targ2_truststore = truststore2

#... and so on

 

 

And then at some point in the logic within the context of a Request, the proxy selects either targ1 or targ2.  At that point you can do this with AssignMessage

 

 

<AssignMessage name='AM-Get-SSLInfo-Settings'>
  <!-- get the variables holding the names of properties that we want to retrieve -->
  <AssignVariable> 
    <Name>var-for-url</Name> 
    <Template>propertyset.myprops.{selected-target}_url</Template>
  </AssignVariable>
  <AssignVariable> 
    <Name>var-for-keyalias</Name> 
    <Template>propertyset.myprops.{selected-target}_keyalias</Template>
  </AssignVariable>
  <AssignVariable> 
    <Name>var-for-keystore</Name> 
    <Template>propertyset.myprops.{selected-target}_keystore</Template>
  </AssignVariable>
  <AssignVariable> 
    <Name>var-for-truststore</Name> 
    <Template>propertyset.myprops.{selected-target}_truststore</Template>
  </AssignVariable>

  <!-- now set the dynamic URL for the ServiceCallout -->
  <AssignVariable> 
    <Name>servicecallout.SC-dynamic.target.url</Name> 
    <Template ref='var-for-url'/>
  </AssignVariable>
</AssignMessage>

 

 

And then in ServiceCallout

 

 

<ServiceCallout name='SC-dynamic'>
  ...
  <HTTPTargetConnection>
    <Properties/>
    <URL>https://this-will-be-overwritten.com</URL>
    <SSLInfo>
        <Enabled>true</Enabled>
        <ClientAuthEnabled>true</ClientAuthEnabled>
        <KeyStore>{var-for-keystore}</KeyStore>
        <KeyAlias>{var-for-keyalias}</KeyAlias>
        <TrustStore>{var-for-truststore}</TrustStore>
        <IgnoreValidationErrors>false</IgnoreValidationErrors>
    </SSLInfo>
  </HTTPTargetConnection>
</ServiceCallout>

 

 

 You could do something similar with a .json file and a JavaScript to select/set variables. You could use the KVM to store these settings, too.  Lots of options, but the pattern is pretty similar.

 

VAP
Bronze 4
Bronze 4

Thanks @dchiesa1  for your detailed explanation!