Describe the bug
Access Azure Key Vault from Gatsby/React app
Initiate access with
this.keyVaultUri = `https://${keyVaultName}.vault.azure.net`;
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
this.keyVaultClient = new SecretClient(this.keyVaultUri, credential);
Get a specific secret lke
get GoogleMapApiKey() {
return (async () => await this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
Get the secret value like:
const mapsKey:KeyVaultSecret = await keyVault.GoogleMapApiKey();
setGoogleMapsApiKey(mapsKey.value ?? '' );
To Reproduce
Steps to reproduce the behavior: Illustrated in the description
Expected behavior
Should retrieve the secret from the Azure Key Vault.
Additional context
This seems related to #9005. This is a Gatsby React app. I am using TypeScript.
@KevinBurton Hello, Kevin!
Kevin, we need your help. Are you running this in a browser with web security enabled? The Key Vault service doesn't currently allow CORS requests, meaning that, if you're running this in a browser with web security enabled (which is the default behavior of most browsers), the Key Vault service won't be able to answer.
In any case, I am most interested in the exact error log. I don't see right away how the steps you're describing relate with the title you used for this issue: _"Request is missing a Bearer or PoP token." with Client token_.
What is the exact error you're getting?
Thank you for your time, we appreciate it.
It seems like I am getting a combination of a CORS error and a
authorization failed message:
[image: image.png]
If I am seeing these errors all stemming from the CORS error then my
question still stands. How do I connect the static web app (Gatsby React)
to my Azure Key Vault?
Thank you.
Kevin
On Tue, Aug 25, 2020 at 11:29 AM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton Hello, Kevin!
Kevin, we need your help. Are you running this in a browser with web
security enabled? The Key Vault service doesn't currently allow CORS
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS requests,
meaning that, if you're running this in a browser with web security enabled
(which is the default behavior of most browsers), the Key Vault service
won't be able to answer.In any case, I am most interested in the exact error log. I don't see
right away how the steps you're describing relate with the title you used
for this issue: "Request is missing a Bearer or PoP token." with Client
token.What is the exact error you're getting?
Thank you for your time, we appreciate it.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-680132773,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3XBT3VDVMU6QSOJ7P3SCPRFPANCNFSM4QKQB2IA
.
@KevinBurton Hello, Mr Burton!
I am unable to load that picture, but I believe I understand anyway. You want to run the Key Vault libraries for TypeScript from a browser, using Gatsby React.
Unfortunately, we are unable to provide support for the browser yet, since the Azure Key Vault service hasn't implemented browser support.
Even though our code does work in the browsers, it only does so without web security, and only for the purposes of testing. By the time the Key Vault service officially releases support for CORS requests, we will be ready to ship a version working for the browsers.
Please let us know if that answers your question.
Thank you for your response. This answers a lot of questions. But I still
have two questions. One, If a web app is deployed in App Service then it is
still a web app and browsers access it. Are you saying that even an App
Service web app cannot access the Key Vault? Two, is there any workaround
in the meantime that my Gatsby web app can get secrets stored in the key
vault?
Regards.
On Tue, Aug 25, 2020 at 3:44 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton Hello, Mr Burton!
I am unable to load that picture, but I believe I understand anyway. You
want to run the Key Vault libraries for TypeScript from a browser, using
Gatsby React.Unfortunately, we are unable to provide support for the browser yet, since
the Azure Key Vault service hasn't implemented browser support.Even though our code does work in the browsers, it only does so without
web security, and only for the purposes of testing. By the time the Key
Vault service officially releases support for CORS requests, we will be
ready to ship a version working for the browsers.Please let us know if that answers your question.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-680260298,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3Q7BOKYR3KLXCFS73DSCQPD7ANCNFSM4QKQB2IA
.
@KevinBurton
Hi! Perhaps this will help: If you're able to run the Key Vault clients from NodeJS, it should work flawlessly.
Would that be viable with your stack?
App Services can work with NodeJS, so that should be ok too.
It's my understanding that Gatsby React is a front-end framework, so I'm guessing it doesn't run in the NodeJS runtime at least. Please correct me if I'm wrong.
There's a work-around for CORS calls, by using proxies. I believe this could help: https://www.gatsbyjs.com/docs/api-proxy/ I'll ask around to see where I can get more information.
I n setting up there apparently is a gatsby-config.js that gets run with
NodeJs. The problem I am running there is that getting secrets from Azure
Key Vault seems to be Promise / asynchronous based.
I will read more about proxies.
On Wed, Aug 26, 2020 at 7:41 AM Daniel RodrĂguez notifications@github.com
wrote:
>
>
@KevinBurton https://github.com/KevinBurton
Hi! Perhaps this will help: If you're able to run the Key Vault clients
from NodeJS, it should work flawlessly.Would that be viable with your stack?
App Services can work with NodeJS, so that should be ok too.
It's my understanding that Gatsby React is a front-end framework, so I'm
guessing it doesn't run in the NodeJS runtime at least. Please correct me
if I'm wrong.There's a work-around for CORS calls, by using proxies. I believe this
could help: https://www.gatsbyjs.com/docs/api-proxy/ I'll ask around to
see where I can get more information.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-680854338,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3UHNYYP7G5URGHTGMLSCT7FTANCNFSM4QKQB2IA
.
@KevinBurton Now that I see that gatsby-config.js, I think I am getting a different idea of what might be happening.
Perhaps this can help.
I see that you have the following in your code:
get GoogleMapApiKey() {
return (async () => await this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
then this:
const mapsKey:KeyVaultSecret = await keyVault.GoogleMapApiKey();
setGoogleMapsApiKey(mapsKey.value ?? '' );
There are many ways to approach this. I'll start with one. Let's call this one "avoiding getters", not because getters are bad, but because it might be clearer to work without them in this case.
The idea with this approach is to avoid having get GoogleMapApiKey as a getter. Getters are used as properties, and not as functions. I'll give you more info after the approach.
You try the following changes to eliminate the getter:
// I'm assuming you have a keyVault object like this one:
let keyVault = {
// 1. Let's change this to be a normal function, not a getter, not an asynchronous function.
getGoogleMapApiKey() {
// 2. This then changes to return the promise of the asynchronous `getSecret`.
// We can work with this promise by itself.
return this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
};
// Then, in the code that uses getGoogleMapApiKey
// Depending on your JavaScript runtime, await calls might not work in the global scope.
// Which is why I'm making the function myAsyncrhonousFunction.
async myAsyncrhonousFunction() {
// 3. getGoogleMapApiKey is now a normal function that returns a promise. We can use await in that case, as follows:
const secret = await keyVault.getGoogleMapApiKey();
console.log(secret); // Yo should be able to see the secret at this point.
}
// We still need to call myAsyncrhonousFunction somewhere.
So, please pardon me if I am explaining too much, but the reason why the getter in this case is unexpected is because a getter is usually used as if it was a property, and not a function, and even less an asynchronous function. As follows:
// Let's imagine we wanted to have an object called truck, as follows:
const truck = {
// Now, imagine that we can't get the brand of the truck immediately,
// So, we can't do simply:
//
// brand: "Mercedes",
//
// We have to use a function, in this scenario.
// For this scenario, let's imagine that the brand comes from an environment variable,
// or just some external source, but for now: process.env.TRUCK_BRAND can work.
// However, we want to still provide an API that reads as if it was a static property.
// That's when the getter shines.
get brand() {
return process.env.TRUCK_BRAND;
}
};
// Then one can read the brand as follows:
console.log(truck.brand);
// See that we didn't have to use the parenthesis, because it is treated as a property.
Getters and setters usually work with a separate entity, let's imagine another source of state. Perhaps you come from this mindset from other languages. So, let's imagine the following scenario:
let stateProvider = {
availableBrands: ["Mercedes"]
};
let truck = {
get brand() {
// In this case, the brand getter only gets the last property in the stateProvider.availableBrands array.
return stateProviders.availableBrands[stateProviders.availableBrands.length - 1];
}
set brand(brandName) {
// The setter then adds a property to this array.
stateProviders.availableBrands.push(brandName);
}
};
// Now, we can read and write the brand of the truck as follows:
console.log(truck.brand); // Should output: "Mercedes".
truck.brand = "Ford"; // Should write to the stateProvider.availableBrands array.
console.log(truck.brand); // Should output: "Ford".
console.log(stateProvider.availableBrands); // Should output: ["Mercedes", "Ford"].
In JavaScript, at least, getters and setters are not supposed to work with asynchronous calls, so the following is not possible:
let truck = {
// Syntax error
get async brand() {}
// Also syntax error
async get brand() {}
}
However, you can return a promise, then deal with the promise separately:
// Let's imagine we have a class called AsyncAPI, with a method called asyncCall() that returns a promise.
const myAsyncApi = new AsyncAPI();
let truck = {
get brand() {
// now we can use the getter to return a promise
return myAsyncApi.asyncCall()
}
}
// We then can read the brand property as a property, get the promise, then treat the promise as a promise
truck.brand.then(function callback(result) {
console.log(result);
});
// We can also make a separate async method to read from this promise using async/await
async brandReader() {
return await truck.brand;
}
// Which we also can use without async/await:
brandReader().then(function callback(result) {
console.log(result);
});
Now another approach, just with async/await functions:
// I'm assuming you have a keyVault object like this one:
let keyVault = {
// 1. Let's change this to be a normal function, not a getter, but indeed an asynchronous function.
async getGoogleMapApiKey() {
// In case you need to work with the secret before returning, you would do as follows:
//
// let secret = await this.keyVaultClient.getSecret('GoogleMapApiKey'));
// // Then we would do something here.
// // Then we can return:
// return secret;
//
// 2. However, since Asynchronous functions don't need to await for promises inside of them,
// We can instead just return the promise of the asynchronous `getSecret`.
return this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
};
// Then, in the code that uses getGoogleMapApiKey....
// Depending on your JavaScript runtime, await calls might not work in the global scope.
// Which is why I'm making the function myAsyncrhonousFunction.
async myAsyncrhonousFunction() {
// 3. getGoogleMapApiKey is now an asynchronous function. We can use await in that case, as follows:
const secret = await keyVault.getGoogleMapApiKey();
console.log(secret); // Yo should be able to see the secret at this point.
}
// We still need to call myAsyncrhonousFunction somewhere.
Let me know if any of those methods helped!
Also, please let me know if this wasn't a good direction. We can take our time investigating the approaches. No rush!
I can see removing the getter if it makes it clearer. The getter in this
case is just returning a function that returns a Promise (hence the
await). Since the ultimate goal of gatsby-config.js is to export
“configuration” it seems to me that somehow I need to turn this
asynchronous call to a synchronous call?
On Wed, Aug 26, 2020 at 11:03 AM Daniel RodrĂguez notifications@github.com
wrote:
>
>
@KevinBurton https://github.com/KevinBurton Now that I see that
gatsby-config.js, I think I am getting a different idea of what might be
happening.Perhaps this can help.
I see that you have the following in your code:
get GoogleMapApiKey() {
return (async () => await this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
then this:
const mapsKey:KeyVaultSecret = await keyVault.GoogleMapApiKey();
setGoogleMapsApiKey(mapsKey.value ?? '' );
There are many ways to approach this. I'll start with one. Let's call this
one "avoiding getters", not because getters are bad, but because it might
be clearer to work without them in this case.Avoiding getters
The idea with this approach is to avoid having get GoogleMapApiKey as a
getter. Getters are used as properties, and not as functions. I'll give you
more info after the approach.You try the following changes to eliminate the getter:
// 1. Let's change this to be a normal function, not a getter, not an asynchronous function.
getGoogleMapApiKey() {
// 2. This then changes to return the promise of the asynchronous
getSecret.// We can work with this promise by itself.
return this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
// Then, in the code that uses getGoogleMapApiKey
// 3. getGoogleMapApiKey is now a normal function that returns a promise. We can use await in that case, as follows:
async myAsyncrhonousFunction() {
// Depending on your Node version, await calls might not work in the global scope.
// Which is why I'm making the function myAsyncrhonousFunction.
const secret = await keyVault.getGoogleMapApiKey();
console.log(secret); // Yo should be able to see the secret at this point.
}
// We still need to call myAsyncrhonousFunction somewhere.
More about getters and setters
So, please pardon me if I am explaining too much, but the reason why the
getter in this case is unexpected is because a getter is usually used as if
it was a property, and not a function, and even less an asynchronous
function. As follows:// Let's imagine we wanted to have an object called truck, as follows:
const truck = {
// Now, imagine that we can't get the brand of the truck immediately,
// because we need to make a database operation.
// So, we can't do simply:
//
// brand: "Mercedes",
//
// We have to use a function, in this scenario.
// For this scenario, let's imagine that the brand comes from an environment variable,
// or just some external source, but for now: process.env.TRUCK_BRAND can work.
// However, we want to still provide an API that reads as if it was a static property.
// That's when the getter shines.
get brand() {
return process.env.TRUCK_BRAND;}
};
// Then one can read the brand as follows:
console.log(truck.brand);
// See that we didn't have to use the parenthesis, because it is treated as a property.
Getters and setters usually work with a separate entity, let's imagine
another source of state. Perhaps you come from this mindset from other
languages. So, let's imagine the following scenario:let stateProvider = {
availableBrands: ["Mercedes"]
};
let truck = {
get brand() {
// In this case, the brand getter only gets the last property in the stateProvider.availableBrands array. return stateProviders.availableBrands[stateProviders.availableBrands.length - 1];}
set brand(brandName) {
// The setter then adds a property to this array. stateProviders.availableBrands.push(brandName);}
};
// Now, we can read and write the brand of the truck as follows:
console.log(truck.brand); // Should output: "Mercedes".
truck.brand = "Ford"; // Should write to the stateProvider.availableBrands array.
console.log(truck.brand); // Should output: "Ford".
console.log(stateProvider.availableBrands); // Should output: ["Mercedes", "Ford"].
In JavaScript, at least, getters and setters are not supposed to work with
asynchronous calls, so the following is not possible:let truck = {
// Syntax error
get async brand() {}
// Also syntax error
async get brand() {}
}
However, you can return a promise, then deal with the promise separately:
// Let's imagine we have a class called AsyncAPI, with a method called asyncCall() that returns a promise.
const myAsyncApi = new AsyncAPI();
let truck = {
get brand() {
// now we can use the getter to return a promise return myAsyncApi.asyncCall()}
}
// We then can read the brand property as a property, get the promise, then treat the promise as a promise
truck.brand.then(function callback(result) {
console.log(result);
});
// We can also make a separate async method to read from this promise using async/await
async brandReader() {
return await truck.brand;
}
// Which we also can use without async/await:
brandReader().then(function callback(result) {
console.log(result);
});
Now another approach, just with async/await functions:
Async/await functions everywhere
// 1. Let's change this to be a normal function, not a getter, but indeed an asynchronous function.
async getGoogleMapApiKey() {
// In case you need to work with the secret before returning, you would do as follows:
//
// let secret = await this.keyVaultClient.getSecret('GoogleMapApiKey'));
// // Then we would do something here.
// // Then we can return:
// return secret;
//
// 2. However, since Asynchronous functions don't need to await for promises inside of them,
// We can instead just return the promise of the asynchronous
getSecret.return this.keyVaultClient.getSecret('GoogleMapApiKey'));
}
// Then, in the code that uses getGoogleMapApiKey....
// 3. getGoogleMapApiKey is now an asynchronous function. We can use await in that case, as follows:
async myAsyncrhonousFunction() {
// Depending on your Node version, await calls might not work in the global scope.
// Which is why I'm making the function myAsyncrhonousFunction.
const secret = await keyVault.getGoogleMapApiKey();
console.log(secret); // Yo should be able to see the secret at this point.
}
// We still need to call myAsyncrhonousFunction somewhere.
Let me know if any of those methods helped!
Also, please let me know if this wasn't a good direction. We can take our
time investigating the approaches. No rush!—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-680972178,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3TXDAW7FHZROFWSVLLSCUW3TANCNFSM4QKQB2IA
.
@KevinBurton oh that also helped me! Thank you.
So far, I'm understanding that you have a gatsby-config.js where you're trying to use KeyVault-Secrets.
Do you mind sharing more of your gatsby-config.js? I want to see more clearly where you're retrieving the secret.
The latest NodeJS version (or at least above 14.3.0) does support top-level await, so you could retrieve your secret in your gatsby-config.js before returning the configuration object. Something like this:
// Imagine this is your gatsby-config.js
// You declare the KeyVault client first.
// Then you retrieve the secret at the top-level, no functions needed:
const secret = await keyVaultClient.getSecret('GoogleMapApiKey');
// Then you proceed with your gatsby-config.js, where you can use that secret as many times as you need.
// ...
Would that help?
Please share more information about your gatsby-config.json if that doesn't help.
Thank you for your help.
Here is my gatsby-config.js
const { ClientSecretCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");
require("dotenv").config({
path: .env.${process.env.NODE_ENV},
})
const KVUri = https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net;
const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
async function getSecrets() {
let keyVaultSecrets = {
'auth0Domain': '',
'auth0ClientId': '',
'auth0Secret': '',
'recaptchaSiteKey': '',
'recaptchaSecretKey': '',
'googleMapsApiKey': '',
'wodifyUser': '',
'wodifyPassword': ''
};
const KVUri = https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net
;
const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID
,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
let retrievedSecret;
retrievedSecret = await client.getSecret('Auth0Domain');
keyVaultSecrets.auth0Domain = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0ClientId');
keyVaultSecrets.auth0ClientId = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0Secret');
keyVaultSecrets.auth0Secret = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSiteKey');
keyVaultSecrets.recaptchaSiteKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSecretKey');
keyVaultSecrets.recaptchaSecretKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('GoogleMapsApiKey');
keyVaultSecrets.googleMapsApiKey = retrievedSecret.value;
process.env.GOOGLE_MAPS_API_KEY = keyVaultSecrets.googleMapsApiKey;
retrievedSecret = await client.getSecret('WodifyUser');
keyVaultSecrets.wodifyUser = retrievedSecret.value;
retrievedSecret = await client.getSecret('WodifyPassword');
keyVaultSecrets.wodifyPassword = retrievedSecret.value;
console.log(keyVaultSecrets);
return keyVaultSecrets;
}
let config = {
siteMetadata: {
title: Great State Strength and Conditioning,
description: Great State web page,
author: @KevinBurton,
auth0Domain: '',
auth0ClientId: '',
auth0Secret: '',
recaptchaSiteKey: '',
recaptchaSecretKey: '',
googleMapsApiKey: '',
wodifyUser: '',
wodifyPassword: ''
},
plugins: [
gatsby-plugin-react-helmet,
{
resolve: gatsby-source-filesystem,
options: {
name: images,
path: ${__dirname}/src/assets,
},
},
gatsby-plugin-styled-components,
gatsby-transformer-sharp,
gatsby-plugin-sharp,
gatsby-plugin-material-ui,
gatsby-plugin-sass,
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// gatsby-plugin-offline,
],
};
getSecrets();
module.exports = config;
The problem is that the export doesn't seem to wait for the asynchronous
call to resolve before returning. Lets just focus on the googMapsApiKey. If
I put a literal string for the value that is exported it seems to work. But
what I want is the value resolved in the Promise. NOTE: There are no
getters here that I have control over.
Kevin
On Wed, Aug 26, 2020 at 11:35 AM Daniel RodrĂguez notifications@github.com
wrote:
>
>
@KevinBurton https://github.com/KevinBurton oh that also helped me!
Thank you.So far, I'm understanding that you have a gatsby-config.js where you're
trying to use KeyVault-Secrets.Do you mind sharing more of your gatsby-config.js? I want to see more
clearly where you're retrieving the secret.The latest NodeJS version (or at least above 14.3.0) does support
top-level await, so you could retrieve your secret in your gatsby-config.js
before returning the configuration object, something like this:// Imagine this is your gatsby-config.js
// You declare the KeyVault client first.
// Then you retrieve the secret at the top-level, no functions needed:
const secret = await keyVaultClient.getSecret('GoogleMapApiKey');
// Then you proceed with your gatsby-config.js, where you can use that secret as many times as you need.
// ...
Would that help?
Please share more information about your gatsby-config.json if that
doesn't help.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-680990575,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3VY5VGESC57SFGEULTSCU2TLANCNFSM4QKQB2IA
.
By the way I am using node v14.8.0, I am not sure what needs to change to
support this asynchronous feature?
On Wed, Aug 26, 2020 at 11:42 AM Kevin Burton ronald.kevin.burton@gmail.com
wrote:
Thank you for your help.
Here is my gatsby-config.js
const { ClientSecretCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");
require("dotenv").config({
path:.env.${process.env.NODE_ENV},
})const KVUri =
https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net;const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID
,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);async function getSecrets() {
let keyVaultSecrets = {
'auth0Domain': '',
'auth0ClientId': '',
'auth0Secret': '',
'recaptchaSiteKey': '',
'recaptchaSecretKey': '',
'googleMapsApiKey': '',
'wodifyUser': '',
'wodifyPassword': ''
};const KVUri =
https://${process.env.AZURE_KEY_VAULT_NAME}. vault.azure.net;const credential = new ClientSecretCredential(process.env.
AZURE_TENANT_ID,
process.env.
AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
let retrievedSecret;
retrievedSecret = await client.getSecret('Auth0Domain');
keyVaultSecrets.auth0Domain = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0ClientId');
keyVaultSecrets.auth0ClientId = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0Secret');
keyVaultSecrets.auth0Secret = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSiteKey');
keyVaultSecrets.recaptchaSiteKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSecretKey');
keyVaultSecrets.recaptchaSecretKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('GoogleMapsApiKey');
keyVaultSecrets.googleMapsApiKey = retrievedSecret.value;
process.env.GOOGLE_MAPS_API_KEY = keyVaultSecrets.googleMapsApiKey;
retrievedSecret = await client.getSecret('WodifyUser');
keyVaultSecrets.wodifyUser = retrievedSecret.value;
retrievedSecret = await client.getSecret('WodifyPassword');
keyVaultSecrets.wodifyPassword = retrievedSecret.value;
console.log(keyVaultSecrets);
return keyVaultSecrets;
}let config = {
siteMetadata: {
title:Great State Strength and Conditioning,
description:Great State web page,
author:@KevinBurton,
auth0Domain: '',
auth0ClientId: '',
auth0Secret: '',
recaptchaSiteKey: '',
recaptchaSecretKey: '',
googleMapsApiKey: '',
wodifyUser: '',
wodifyPassword: ''
},
plugins: [
gatsby-plugin-react-helmet,
{
resolve:gatsby-source-filesystem,
options: {
name:images,
path:${__dirname}/src/assets,
},
},
gatsby-plugin-styled-components,
gatsby-transformer-sharp,
gatsby-plugin-sharp,
gatsby-plugin-material-ui,
gatsby-plugin-sass,// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
//gatsby-plugin-offline,
],
};getSecrets();
module.exports = config;
The problem is that the export doesn't seem to wait for the asynchronous
call to resolve before returning. Lets just focus on the googMapsApiKey. If
I put a literal string for the value that is exported it seems to work. But
what I want is the value resolved in the Promise. NOTE: There are no
getters here that I have control over.Kevin
On Wed, Aug 26, 2020 at 11:35 AM Daniel RodrĂguez <
[email protected]> wrote:>
>@KevinBurton https://github.com/KevinBurton oh that also helped me!
Thank you.So far, I'm understanding that you have a gatsby-config.js where you're
trying to use KeyVault-Secrets.Do you mind sharing more of your gatsby-config.js? I want to see more
clearly where you're retrieving the secret.The latest NodeJS version (or at least above 14.3.0) does support
top-level await, so you could retrieve your secret in your gatsby-config.js
before returning the configuration object, something like this:// Imagine this is your gatsby-config.js
// You declare the KeyVault client first.
// Then you retrieve the secret at the top-level, no functions needed:
const secret = await keyVaultClient.getSecret('GoogleMapApiKey');
// Then you proceed with your gatsby-config.js, where you can use that secret as many times as you need.
// ...
Would that help?
Please share more information about your gatsby-config.json if that
doesn't help.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-680990575,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3VY5VGESC57SFGEULTSCU2TLANCNFSM4QKQB2IA
.
@KevinBurton ok ok! That gives me enough information to help you, I believe.
Let's keep up this pace. I'll give you a quick answer, in the form of steps to follow:
config outside of getSecrets. Just let config = {} helps.getSecrets, you don't need to re-declare config, you can do config = { /* your object */ without let, var or const. The idea is that we will be writing over the top-level config. We could do better than this, but as a step towards the solution, this might be good enough for now.getSecrets(), place an await before the call, as in await getSecrets(). I'm assuming this will work. I'll give it a try after posting this, just in case.After that, config should be populated before it's sent to module.exports. You can try debugging it or logging some portion of it to see if you're able to see what you are expecting.
I'm ready to answer again, Mr Burton!
@KevinBurton alright, for the top level await, I had to add this property and value to my package.json:
"type": "module",
After that I was able to run the code I sent you with the top-level await. I hope that helps!
So now gatsby-config looks like:
const { ClientSecretCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");
require("dotenv").config({
path: .env.${process.env.NODE_ENV},
})
const KVUri = https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net;
const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
async function getSecrets() {
let keyVaultSecrets = {
'auth0Domain': '',
'auth0ClientId': '',
'auth0Secret': '',
'recaptchaSiteKey': '',
'recaptchaSecretKey': '',
'googleMapsApiKey': '',
'wodifyUser': '',
'wodifyPassword': ''
};
const KVUri = https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net
;
const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID
,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
let retrievedSecret;
retrievedSecret = await client.getSecret('Auth0Domain');
keyVaultSecrets.auth0Domain = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0ClientId');
keyVaultSecrets.auth0ClientId = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0Secret');
keyVaultSecrets.auth0Secret = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSiteKey');
keyVaultSecrets.recaptchaSiteKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSecretKey');
keyVaultSecrets.recaptchaSecretKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('GoogleMapsApiKey');
keyVaultSecrets.googleMapsApiKey = retrievedSecret.value;
process.env.GOOGLE_MAPS_API_KEY = keyVaultSecrets.googleMapsApiKey;
retrievedSecret = await client.getSecret('WodifyUser');
keyVaultSecrets.wodifyUser = retrievedSecret.value;
retrievedSecret = await client.getSecret('WodifyPassword');
keyVaultSecrets.wodifyPassword = retrievedSecret.value;
// console.log(keyVaultSecrets);
return keyVaultSecrets;
}
const keyVaultSecrets = await getSecrets();
let config = {
siteMetadata: {
title: Great State Strength and Conditioning,
description: Great State web page,
author: @KevinBurton,
},
plugins: [
gatsby-plugin-react-helmet,
{
resolve: gatsby-source-filesystem,
options: {
name: images,
path: ${__dirname}/src/assets,
},
},
gatsby-plugin-styled-components,
gatsby-transformer-sharp,
gatsby-plugin-sharp,
gatsby-plugin-material-ui,
gatsby-plugin-sass,
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// gatsby-plugin-offline,
],
};
module.exports = config;
Adding
"author": "Kevin Burton rkevinburton@charter.net",
"type": "module",
"dependencies": {
to package.json. But now I get
yarn start
yarn run v1.22.4
$ yarn run develop
$ gatsby develop
internal/process/esm_loader.js:74
internalBinding('errors').triggerUncaughtException(
^
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for
C:\Users\RKevi\source\repos\GreatState-gatsby.cache\tmp-30928-4nOKL4bzTny6
at Loader.defaultGetFormat [as _getFormat]
(internal/modules/esm/get_format.js:65:15)
at Loader.getFormat (internal/modules/esm/loader.js:101:42)
at Loader.getModuleJob (internal/modules/esm/loader.js:230:31)
at async Loader.import (internal/modules/esm/loader.js:164:17)
at async Object.loadESM (internal/process/esm_loader.js:68:5) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this
command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this
command.
If I take the "type":"module" out of package.json I get
For help, see: https://nodejs.org/en/docs/inspector
ERROR #10123 CONFIG
We encountered an error while trying to load your site's gatsby-config.
Please fix the error and try again.
Error: C:\Users\RKevi\source\repos\GreatState-gatsbygatsby-config.js:55
const keyVaultSecrets = await getSecrets();
^^^^^
SyntaxError: await is only valid in async function
On Wed, Aug 26, 2020 at 12:04 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton alright, for the top level
await, I had to add this property and value to my package.json:"type": "module",
After that I was able to run the code I sent you with the top-level await.
I hope that helps!—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681006345,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3QHGUKLKGF4QW6MFALSCU57NANCNFSM4QKQB2IA
.
@KevinBurton Ok, I like that update! I think we're getting closer. Here's an idea, continuing from what you have updated:
Instead of getting all the secrets at once, assign only the promise, with the following change:
- const keyVaultSecrets = await getSecrets();
+ const secretsPromise = getSecrets();
Then, I'm assuming you are using keyVaultSecrets from a plugin, or something like a function. If that function is an asynchronous function, you can do the following:
async myFunction() {
const secrets = await secretsPromise;
// Then you can use the secrets
}
If that function isn't an asynchronous function, you can use the promises syntax:
myFunction(callback) {
secretsPromise.then(function (secrets) {
// Here you can use the secrets.
// In this case, at some point you will need to use something like a callback that you will receive to indicate that you're done.
callback(); // We're done here.
});
}
Let me know if that is feasible!
Oops I forgot to add in the secrets to the config.
siteMetadata: {
title: Great State Strength and Conditioning,
description: Great State web page,
author: @KevinBurton,
...keyVaultSecrets
},
Kevin
On Wed, Aug 26, 2020 at 12:15 PM Kevin Burton ronald.kevin.burton@gmail.com
wrote:
So now gatsby-config looks like:
const { ClientSecretCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");
require("dotenv").config({
path:.env.${process.env.NODE_ENV},
})const KVUri =
https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net;const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID
,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);async function getSecrets() {
let keyVaultSecrets = {
'auth0Domain': '',
'auth0ClientId': '',
'auth0Secret': '',
'recaptchaSiteKey': '',
'recaptchaSecretKey': '',
'googleMapsApiKey': '',
'wodifyUser': '',
'wodifyPassword': ''
};const KVUri =
https://${process.env.AZURE_KEY_VAULT_NAME}. vault.azure.net;const credential = new ClientSecretCredential(process.env.
AZURE_TENANT_ID,
process.env.
AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
let retrievedSecret;
retrievedSecret = await client.getSecret('Auth0Domain');
keyVaultSecrets.auth0Domain = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0ClientId');
keyVaultSecrets.auth0ClientId = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0Secret');
keyVaultSecrets.auth0Secret = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSiteKey');
keyVaultSecrets.recaptchaSiteKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSecretKey');
keyVaultSecrets.recaptchaSecretKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('GoogleMapsApiKey');
keyVaultSecrets.googleMapsApiKey = retrievedSecret.value;
process.env.GOOGLE_MAPS_API_KEY = keyVaultSecrets.googleMapsApiKey;
retrievedSecret = await client.getSecret('WodifyUser');
keyVaultSecrets.wodifyUser = retrievedSecret.value;
retrievedSecret = await client.getSecret('WodifyPassword');
keyVaultSecrets.wodifyPassword = retrievedSecret.value;
// console.log(keyVaultSecrets);
return keyVaultSecrets;
}const keyVaultSecrets = await getSecrets();
let config = {
siteMetadata: {
title:Great State Strength and Conditioning,
description:Great State web page,
author:@KevinBurton,
},
plugins: [
gatsby-plugin-react-helmet,
{
resolve:gatsby-source-filesystem,
options: {
name:images,
path:${__dirname}/src/assets,
},
},
gatsby-plugin-styled-components,
gatsby-transformer-sharp,
gatsby-plugin-sharp,
gatsby-plugin-material-ui,
gatsby-plugin-sass,// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
//gatsby-plugin-offline,
],
};module.exports = config;
Adding
"author": "Kevin Burton rkevinburton@charter.net",
"type": "module",
"dependencies": {to package.json. But now I get
yarn start
yarn run v1.22.4
$ yarn run develop
$ gatsby develop
internal/process/esm_loader.js:74
internalBinding('errors').triggerUncaughtException(
^TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for
C:\Users\RKevi\source\repos\GreatState-gatsby.cache\tmp-30928-4nOKL4bzTny6
at Loader.defaultGetFormat [as _getFormat]
(internal/modules/esm/get_format.js:65:15)
at Loader.getFormat (internal/modules/esm/loader.js:101:42)
at Loader.getModuleJob (internal/modules/esm/loader.js:230:31)
at async Loader.import (internal/modules/esm/loader.js:164:17)
at async Object.loadESM (internal/process/esm_loader.js:68:5) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about
this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about
this command.If I take the "type":"module" out of package.json I get
For help, see: https://nodejs.org/en/docs/inspector
ERROR #10123 CONFIG
We encountered an error while trying to load your site's gatsby-config.
Please fix the error and try again.Error: C:\Users\RKevi\source\repos\GreatState-gatsbygatsby-config.js:55
const keyVaultSecrets = await getSecrets();
^^^^^
SyntaxError: await is only valid in async function
- v8-compile-cache.js:226 NativeCompileCache._moduleCompile
On Wed, Aug 26, 2020 at 12:04 PM Daniel RodrĂguez <
[email protected]> wrote:@KevinBurton https://github.com/KevinBurton alright, for the top level
await, I had to add this property and value to my package.json:"type": "module",
After that I was able to run the code I sent you with the top-level
await. I hope that helps!—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681006345,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3QHGUKLKGF4QW6MFALSCU57NANCNFSM4QKQB2IA
.
@KevinBurton would it be possible to provide a function for your code instead of adding the secrets as part of the configuration object? I haven't gotten deeper in Gatsby, but I'm guessing you can provide some form of method that can be used by the rest of the program, rather than just config properties. This will give us a lot more flexibility on the possible answers.
If you absolutely can't use a method/function and must use configuration properties, like the siteMetadata one, please let me know. We can think of something.
The sensible approach seemed to be to use plugins, or at least as I am searching through the Gatsby docs.
This issue might be relevant: https://github.com/gatsbyjs/gatsby/issues/11128
Now my gatsby-config.js looks like:
const { ClientSecretCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");
require("dotenv").config({
path: .env.${process.env.NODE_ENV},
})
const KVUri = https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net;
const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
async function getSecrets() {
let keyVaultSecrets = {
'auth0Domain': '',
'auth0ClientId': '',
'auth0Secret': '',
'recaptchaSiteKey': '',
'recaptchaSecretKey': '',
'googleMapsApiKey': '',
'wodifyUser': '',
'wodifyPassword': ''
};
const KVUri = https://${process.env.AZURE_KEY_VAULT_NAME}.vault.azure.net
;
const credential = new ClientSecretCredential(process.env.AZURE_TENANT_ID
,
process.env.AZURE_CLIENT_ID,
process.env.
AZURE_CLIENT_SECRET);
const client = new SecretClient(KVUri, credential);
let retrievedSecret;
retrievedSecret = await client.getSecret('Auth0Domain');
keyVaultSecrets.auth0Domain = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0ClientId');
keyVaultSecrets.auth0ClientId = retrievedSecret.value;
retrievedSecret = await client.getSecret('Auth0Secret');
keyVaultSecrets.auth0Secret = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSiteKey');
keyVaultSecrets.recaptchaSiteKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('RecaptchaSecretKey');
keyVaultSecrets.recaptchaSecretKey = retrievedSecret.value;
retrievedSecret = await client.getSecret('GoogleMapsApiKey');
keyVaultSecrets.googleMapsApiKey = retrievedSecret.value;
process.env.GOOGLE_MAPS_API_KEY = keyVaultSecrets.googleMapsApiKey;
retrievedSecret = await client.getSecret('WodifyUser');
keyVaultSecrets.wodifyUser = retrievedSecret.value;
retrievedSecret = await client.getSecret('WodifyPassword');
keyVaultSecrets.wodifyPassword = retrievedSecret.value;
// console.log(keyVaultSecrets);
return keyVaultSecrets;
}
let config = {};
const secretsPromise = getSecrets();
async function myFunction() {
const secrets = await secretsPromise;
config = {
siteMetadata: {
title: Great State Strength and Conditioning,
description: Great State web page,
author: @KevinBurton,
...secrets
},
plugins: [
gatsby-plugin-react-helmet,
{
resolve: gatsby-source-filesystem,
options: {
name: images,
path: ${__dirname}/src/assets,
},
},
gatsby-plugin-styled-components,
gatsby-transformer-sharp,
gatsby-plugin-sharp,
gatsby-plugin-material-ui,
gatsby-plugin-sass,
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// gatsby-plugin-offline,
],
};
}
module.exports = config;
But this also doesn't work as now the variables are not properly exported
and I get errors like
ERROR #85901 GRAPHQL
There was an error in your GraphQL query:
Unknown type "ImageSharpFixed".
GraphQL request:2:37
1 |
2 | fragment GatsbyImageSharpFixed on ImageSharpFixed {
which says to me that the export didn't wait for the configuration.
The reason that I am putting them into the secrets into the configuration
object stems back to Azure not being able to be called on the client-side.
So the "hook" that I am using is to get the secrets server side and then
query for them on the client side.
Kevin
On Wed, Aug 26, 2020 at 12:27 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton would it be possible to
provide a function for your code instead of adding the secrets as part of
the configuration object? I haven't gotten deeper in Gatsby, but I'm
guessing you can provide some form of method that can be used by the rest
of the program, rather than just config properties. This will give us a lot
more flexibility on the possible answers.If you absolutely can't use a method/function and must use configuration
properties, like the siteMetadata one, please let me know. We can think of
something.The sensible approach seemed to be to use plugins, or at least as I am
searching through the Gatsby docs.This issue might be relevant: gatsbyjs/gatsby#11128
https://github.com/gatsbyjs/gatsby/issues/11128—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681018467,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3SGMYY2JHL6WRUBNZLSCVAZFANCNFSM4QKQB2IA
.
@KevinBurton Instead of adding the secrets to the metadata, another approach would be to add an endpoint from which you can retrieve the secrets. Would that be a viable approach?
@KevinBurton some Gatsby users seem to be using plugins in the configuration object to provide an asynchronous way of retrieving configuration, as shown here: https://github.com/gatsbyjs/gatsby/issues/11128#issuecomment-458609530 would that approach be viable for you?
I guess. That endpoint would have to go to its server to get the secrets. I
am not sure how this works for deploying and debugging an app.
On Wed, Aug 26, 2020 at 12:55 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton Instead of adding the
secrets to the metadata, another approach would be to add an endpoint from
which you can retrieve the secrets. Would that be a viable approach?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681031999,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3S4RXDUBC5MVCIXAJTSCVD7JANCNFSM4QKQB2IA
.
@KevinBurton I might be able to dig deeper and try to deploy a Gatsby app myself later this week or next week, if that helps.
I am too new to Gatsby to understand how this all works but I will look
into it. The big hurdle for me right now is the comment "and you could
invoke that and await inside your plugin", which indicates to me that I
need to develop and use a plugin which right now I don't know how to do.
On Wed, Aug 26, 2020 at 12:57 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton some Gatsby users seem to
be using plugins in the configuration object to provide an asynchronous way
of retrieving configuration, as shown here: gatsbyjs/gatsby#11128
(comment)
https://github.com/gatsbyjs/gatsby/issues/11128#issuecomment-458609530
would that approach be viable for you?—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681033189,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3V4U3C24ELUMBXSWW3SCVEH3ANCNFSM4QKQB2IA
.
It would. If you have time. Thank you.
Kevin
On Wed, Aug 26, 2020 at 1:01 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton I might be able to dig
deeper and try to deploy a Gatsby app myself later this week or next week,
if that helps.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681035623,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3R75THFO4ADVLSCMB3SCVEZDANCNFSM4QKQB2IA
.
@KevinBurton that's a good spot to be in! So many things to learn! Alright, good luck with that study!
If you happen to find the solution before me, please report back.
I'll put some time over the weekend trying to deploy a Gatsby App using Azure App Service and our KeyVault clients to see if I can come up with something else.
I'm also asking internally in case somebody else knows more than me about this.
In case none of us has a better answer soon, see you in some days! good luck!
One more thought for which I have NO experience is to add Azure function to
the app. Since it is already being deployed to static web site on Azure
this seems like a natural place to put a function?
Again thank you for the help.
Kevin
On Wed, Aug 26, 2020 at 1:05 PM Daniel RodrĂguez notifications@github.com
wrote:
@KevinBurton https://github.com/KevinBurton that's a good spot to be
in! So many things to learn! Alright, good luck with that study!If you happen to find the solution before me, please report back.
I'll put some time over the weekend trying to deploy a Gatsby App using
Azure App Service and our KeyVault clients to see if I can come up with
something else.I'm also asking internally in case somebody else knows more than me about
this.In case none of us has a better answer soon, see you in some days! good
luck!—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Azure/azure-sdk-for-js/issues/10828#issuecomment-681037320,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAUFM3XCCTFI5CIADUNDFS3SCVFFZANCNFSM4QKQB2IA
.
@KevinBurton I'll add an Azure Function to the mix when I get to work with this!
@KevinBurton We might have an update for this issue later this year. For now we're pretty busy. I hope things are good on your side!
Hey @KevinBurton and @sadasant,
Thanks for the great discussion here. We will be continuing the efforts in #12967 at the end of which we hope to have some guidance around using Key Vault in web apps.