Hi!
I was recently experimenting with all sorts of @auth
rules and came across a use-case, I am obviously not alone with - see here.
Scenario
In some occasions it might be useful to run queries (eg. from an external backend) by using an API key. We have no access to an ID token. Therefore it would be nice if eg. the Admin Key included via DG-Auth: <admin-key>
in the request header, could completely bypass all @auth
rules for a node. At the moment this is not possible. We would have to have multiple different queries via lambda.
What we have
Assume this setup
type Test {
id: ID!
name: String
}
Anonymous Access for both write
and read
is turned off for Test
. If we now run a query
query QueryWithApiKey {
queryTest {
id
name
}
}
and pass "DG-Auth": "<client-or-admin-api-key>"
into the header, the query works.
However, if we change the access rules for Test
(write
and read
is allowed by anonymous) and add an @auth
rule to it
type Test @auth(
query: { rule: "{ $isAuthenticated: { eq: \"true\" } }" }
) {
id: ID!
name: String
}
the above query fails because no ID Token which includes the parameter isAuthenticated
is submitted in the header. This is a bit of a weird behaviour and not really expected since passing an API key usually gives you all the rights.
Further Testing
Nonetheless, I have been testing further and this is where interfaces came into my mind. I thought defining
interface TestQuery @auth(
query: { rule: "{ $isAuthenticated: { eq: \"true\" } }" }
) {
id: ID!
name: String
}
type Test implements TestQuery {
id: ID!
name: String
}
and reworking write
and read
access from Test
, would do the job. Unfortunately, Dgraph adds the interface @auth
rule with a union OR
rule to type Test
- which is basically the same result as before.
The (very bad) workaround
A workaround would probably be that we define separate types with different rules and leave the actual Test
without anonymous access.
type TestQuery @auth(
query: { rule: "{ $isAuthenticated: { eq: \"true\" } }" }
) {
test: Test
}
type Test {
id: ID!
name: String
}
where TestQuery
could be publicly queryable (via ID Token including isAuthenticated
) and Test
is not accessible and could be queried via API key.
The Request
In order to not fiddle around with the schema too much it would be very nice if:
- the Client Api Key stays like it is (can only do client side queries and does not ignore
@auth
) - the Admin Api key can do admin stuff, client stuff PLUS ignores
@auth
for client stuff