I have two Google Cloud Functions, one of them 'caller' creates a Cloud Task which then calls a http endpoint tied to a different Cloud Function 'worker'
When I assign allUsers to the worker function as a Cloud Functions Invoker this works. When I remove this permission and assign the caller function Service Account instead as the Invoker, it fails. What am I doing wrong?
If there is any code it would be helpful to see to diagnose this, let me know. It doesn't seem to be a code issue though since the same code passes or fails depending on the permissions I have set.My permissions look like this:
...@appspot.gserviceaccount.com App Engine default service account Cloud Functions Invoker
export function main(
project:any, // Your GCP Project id
queue:any, // Name of your Queue
location:any, // The GCP region of your queue
url:any, // The full url path that the request will be sent to
payload:any, // The task HTTP request body
inSeconds = 0 // Delay in task execution
) {
// [START cloud_tasks_create_http_task]
// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');
// Instantiates a client.
const client = new CloudTasksClient();
async function createHttpTask() {
// TODO(developer): Uncomment these lines and replace with your values.
// const project = 'my-project-id';
// const queue = 'my-queue';
// const location = 'us-central1';
// const url = 'https://example.com/taskhandler';
// const payload = 'Hello, World!';
// const inSeconds = 180;
// Construct the fully qualified queue name.
const parent = client.queuePath(project, location, queue);
const task = {
httpRequest: {
httpMethod: 'POST',
url,
body: '',
headers: {
"Content-Type": "application/json",
},
},
scheduleTime: {}
};
if (payload) {
const convertedPayload = JSON.stringify(payload);
task.httpRequest.body = Buffer.from(convertedPayload).toString('base64');
}
if (inSeconds) {
// The time when the task is scheduled to be attempted.
task.scheduleTime = {
seconds: inSeconds + Date.now() / 1000,
};
}
// Send create task request.
console.log('Sending task:');
console.log(task);
const request = {parent: parent, task: task};
const [response] = await client.createTask(request);
console.log(`Created task ${response.name}`);
}
createHttpTask();
// [END cloud_tasks_create_http_task]
}
Oh fine, you forgot the OIDC part
const task = {
httpRequest: {
httpMethod: 'POST',
url,
body: '',
headers: {
"Content-Type": "application/json",
},
######### This part is missing #############
oidcToken: {
serviceAccountEmail,
},
######### End of missing part #############
},
scheduleTime: {}
};
Set the service account email that you want to use to call your cloud functions, of course a service account with the permission to invoke the cloud functions and it should work.