Reputation: 1247
I created a service account email and added cloudfunctions.invoker
role to the email so I can make sure only cloud tasks can trigger cloud functions, and I removed AllUsers
role. But when cloud tasks tried to run cloud function, the status code is UNAUTHENTICATED(16): HTTP status code 401
and execution failed.
My current code and console is like this.
index.ts
export const addTasks = functions.https.onCall((data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError('failed-precondition', 'You are not authenticated.')
}
const client = new tasks.CloudTasksClient()
const projectId = functions.config().project.id
const queue = 'queue'
const location = functions.config().project.location
const parent = client.queuePath(projectId, location, queue)
const url = `https://${location}-${projectId}.cloudfunctions.net/executeSomething`
const serviceAccountEmail = functions.config().project.email
const task: tasks.protos.google.cloud.tasks.v2.ITask = {
httpRequest: {
httpMethod: 'POST',
url: url,
oidcToken: {
serviceAccountEmail: serviceAccountEmail,
},
},
scheduleTime: {
seconds: ...,
},
}
const request: tasks.protos.google.cloud.tasks.v2.ICreateTaskRequest = {
parent: parent,
task: task,
}
return client.createTask(request)
}
My cloud function's console
I added the cloud functions invoker role to the service account email.
My firebase project environment variables
When I added AllUsers
role to cloud functions, it works as expected so I am sure I made a mistake when resrticting access. What am I missing?
Update:
My cloud tasks console
Upvotes: 5
Views: 1809
Reputation: 2222
Adding audience
did the trick for me.
Here is how my task object look like -
const task = {
httpRequest: {
httpMethod: 'POST',
url,
headers: { 'Content-Type': 'application/json' },
oidcToken: {
serviceAccountEmail: sa,
audience: aud
},
},
};
Upvotes: 0
Reputation: 49150
for me removing audience: new URL(url).origin,
from oidcToken
object inside task
resolved the UNAUTHENTICATED(16): HTTP status code 401
issue.
const task = {
httpRequest: {
httpMethod: 'POST',
url,
oidcToken: {
serviceAccountEmail: email,
//audience: new URL(url).origin,
},
headers: {
'Content-Type': 'application/json',
},
body,
},
};
Upvotes: 2
Reputation: 75715
Your OIDC token seems broken against the specification
Simply provide the email, without the attribute name like in this example, or use the snake_case like described in the spec
Upvotes: 0