Dear Team,
I hope you are doing well,
I have a little challenge see the below scenario.
I would like to set operators in KVM and the value is above JSON.
Then inside the developer app I would like to set the custom attribute name it operator and value is operator1 for example.
Then once this consumer use his developer app credentials I will take the custom attribute and pass it to json after I extract from KVM to extract specific operator password and then pass it to the backend.
The problem is it is dealing with in in flow variables as a string not json how can I solve this with out any custom code only use KVM, AssignMessage and ExtractVariables.
and I do not want to set in the request payload because my request is post and if I set the value in the request payload it will override my request JSON body.
once I extract value from flow and handle as a JSON.
Best Regards,
Amer Hijazi
Solved! Go to Solution.
Since you want to use the KVM as a JSON and avoid creating multiple separate keys, here’s a creative approach you can try using AssignMessage and ExtractVariables policies.
To be honest, this approach looks a bit unusual to me—personally, I’d recommend splitting the keys for each operator or parse with a JavaScript policy for better clarity. But, if you prefer to stick with a limited set of policies, this method will work.
You can create an AssignMessage policy that converts the value retrieved from the KVM into a JSON object. This policy prepares the JSON path expression to extract the specific password you need based on the operatorKey, which I assume comes from the app object:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-2">
<DisplayName>AM-2</DisplayName>
<Set>
<Payload contentType="application/json">
{private.operatorPasswords} <!-- This comes from your KVM -->
</Payload>
</Set>
<AssignVariable>
<Name>jsonPathExpr</Name>
<Template>$.{operatorKey}</Template> <!-- Prepare the JSONPath based on the operatorKey -->
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="true" transport="http" type="request">operatorPasswordsObject</AssignTo> <!-- Create a new message with JSON payload -->
</AssignMessage>
Step 2: Extract the Password with JSONPath
Next, you can use the ExtractVariables policy to extract the password from the newly created JSON object using the JSONPath expression:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables continueOnError="false" enabled="true" name="EV-1">
<DisplayName>EV-1</DisplayName>
<Properties/>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<JSONPayload>
<Variable name="operatorPassword">
<JSONPath>{jsonPathExpr}</JSONPath> <!-- Use the JSONPath expression to extract the password -->
</Variable>
</JSONPayload>
<Source>operatorPasswordsObject</Source> <!-- Extract from the new JSON object created in the previous step -->
<VariablePrefix>private</VariablePrefix>
</ExtractVariables>
This policy retrieves the specific operatorPassword based on the operatorKey and stores it in the variable private.operatorPassword.
Again, while splitting the keys would simplify things, if you’re set on keeping a single JSON, this method should meet your needs.
This approach can generate a lot of flow variables, especially ones that contain your passwords, like operatorPasswordsObject.content. It’s critical to mask these flow variables to prevent passwords from being exposed in Apigee Trace. Make sure you properly mask any variables containing sensitive information to avoid data leaks.
Let me know if this works for your use case!
Dear @nmarkevich ,
Thank you for your efforts
Your answer to assign the value to the payload will override my current payload.
<Set>
<Payload contentType="application/json">
{private.operatorPasswords} <!-- This comes from your KVM -->
</Payload>
</Set>
I found another solution only using KVM with ExtractVariables policies as below.
Then I will use ExtractVariables as below :
I was got an error because, in the extract variable policy, I was using the wrong source.
I will set the company name inside the custom attribute to pass it automatically once the consumer uses his credentials.
Best Regards,
Amer Hijazi
Or let me make it simple how can I extract value form josn after I retrieve it from the KVM because I think it considers as a String.
How can I take operator5 for example.
Amer Hijazi
Hi @Amer-Hijazi,
If you need to extract a value from a string that is represented as JSON, you first need to cast it to a JavaScript object. After that, you can access the object's properties.
Here’s an example using a JavaScript policy:
var operators = context.getVariable('operators'); // The JSON string from KVM
var operatorKey = context.getVariable('verifyapikey...')// The key for the operator
if (operators === undefined || operatorKey === undefined) {
throw new Error('Operators or operator key is missing');
}
var parsedOperators = JSON.parse(operators); // Convert JSON string to object
var operatorPassword = parsedOperators[operatorKey]; // Extract operator's password
if (operatorPassword === undefined) {
throw new Error(`No password specified for operator ${operatorKey}`);
}
context.setVariable('private.operatorPassword', operatorPassword); // Set it as a flow variable
Also, one thing to keep in mind: user passwords can show up unmasked in the Apigee Trace tool, which can lead to potential exposure. Did you know that CodeSent knows the context of your API flows and helps you detect leaks from private or masked variables? You might want to check out the rules here and see how it can help secure your sensitive data.
Let me know if this helps, and feel free to reach out if you need further clarification!
I do not want to use custom code
Hey @Amer-Hijazi,
Since you're looking to retrieve operator-specific passwords from the KVM without using custom code, how about storing each operator’s password under a separate key in the KVM? You can then retrieve the password dynamically at runtime based on the operator’s ID.
For example, store each operator’s password under a unique key (like their operator_id) in the KVM, and retrieve it as follows:
<KeyValueMapOperations continueOnError="false" enabled="true" name="KVM.OperatorPassword" mapIdentifier="map_name">
<!-- Retrieve operator password from KVM -->
<Get assignTo="private.operatorPassword">
<Key>
<Parameter ref="operator_id"/> <!-- The operator's ID is used as the key -->
</Key>
</Get>
</KeyValueMapOperations >
This way, you can access each operator's password by referring to their unique ID. This method avoids custom code while still allowing you to dynamically fetch the correct password for each operator at runtime.
Let me know if this approach works for your use case!
Thank You for your support,
I want to use it as a json no need to create multiple separate keys.
Thank you
Since you want to use the KVM as a JSON and avoid creating multiple separate keys, here’s a creative approach you can try using AssignMessage and ExtractVariables policies.
To be honest, this approach looks a bit unusual to me—personally, I’d recommend splitting the keys for each operator or parse with a JavaScript policy for better clarity. But, if you prefer to stick with a limited set of policies, this method will work.
You can create an AssignMessage policy that converts the value retrieved from the KVM into a JSON object. This policy prepares the JSON path expression to extract the specific password you need based on the operatorKey, which I assume comes from the app object:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-2">
<DisplayName>AM-2</DisplayName>
<Set>
<Payload contentType="application/json">
{private.operatorPasswords} <!-- This comes from your KVM -->
</Payload>
</Set>
<AssignVariable>
<Name>jsonPathExpr</Name>
<Template>$.{operatorKey}</Template> <!-- Prepare the JSONPath based on the operatorKey -->
</AssignVariable>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="true" transport="http" type="request">operatorPasswordsObject</AssignTo> <!-- Create a new message with JSON payload -->
</AssignMessage>
Step 2: Extract the Password with JSONPath
Next, you can use the ExtractVariables policy to extract the password from the newly created JSON object using the JSONPath expression:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables continueOnError="false" enabled="true" name="EV-1">
<DisplayName>EV-1</DisplayName>
<Properties/>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<JSONPayload>
<Variable name="operatorPassword">
<JSONPath>{jsonPathExpr}</JSONPath> <!-- Use the JSONPath expression to extract the password -->
</Variable>
</JSONPayload>
<Source>operatorPasswordsObject</Source> <!-- Extract from the new JSON object created in the previous step -->
<VariablePrefix>private</VariablePrefix>
</ExtractVariables>
This policy retrieves the specific operatorPassword based on the operatorKey and stores it in the variable private.operatorPassword.
Again, while splitting the keys would simplify things, if you’re set on keeping a single JSON, this method should meet your needs.
This approach can generate a lot of flow variables, especially ones that contain your passwords, like operatorPasswordsObject.content. It’s critical to mask these flow variables to prevent passwords from being exposed in Apigee Trace. Make sure you properly mask any variables containing sensitive information to avoid data leaks.
Let me know if this works for your use case!
Dear @nmarkevich ,
Thank you for your efforts
Your answer to assign the value to the payload will override my current payload.
<Set>
<Payload contentType="application/json">
{private.operatorPasswords} <!-- This comes from your KVM -->
</Payload>
</Set>
I found another solution only using KVM with ExtractVariables policies as below.
Then I will use ExtractVariables as below :
I was got an error because, in the extract variable policy, I was using the wrong source.
I will set the company name inside the custom attribute to pass it automatically once the consumer uses his credentials.
Best Regards,
Amer Hijazi
@Amer-Hijazi wrote:Your answer to assign the value to the payload will override my current payload.
Have you tried it? Because it shouldn't override your current payload if you create a new object via AssignTo like this:
<AssignTo createNew="true" transport="http" type="request">operatorPasswordsObject</AssignTo> <!-- Create a new message with JSON payload -->
This ensures the original payload remains untouched while creating a new request object specifically for handling your KVM JSON.
But nevermind, passing the JSON string to the ExtractVariables policy would also work just fine. Good job on figuring that out!
Dear @nmarkevich You are correct I just try it and it works fine.
Thank You
I’m glad to hear that solution worked for you! 🎉
By the way, if you're looking for some tips on securing your Apigee proxies, I recently put together a post that covers key practices for enhancing security. It walks through a few straightforward steps to protect your APIs, from input validation to handling sensitive data.
Feel free to check it out: How to Start Securing Your Proxy
Let me know if you have any questions or want to discuss any of the steps further!
Best,
Nikita
Dear @nmarkevich ,
That’s amazing article thank you very much for sharing such great information.
Best regards
Amer Hijazi
Hi @Amer-Hijazi,
Thank you so much for your kind words! I’m glad you found the first article helpful.
I just released the second part of the series, which goes even deeper into advanced Apigee security practices. This time, I’ve included some real-world examples of what not to do, based on issues I’ve seen in the wild. It covers topics like secure logging, robust error handling, and more!
Feel free to take a look: Apigee Best Security Practices - Part 2.
I’d love to hear your thoughts on this one too!
Best,
Nikita