Experience Report for Feature Request
Note: Feature requests are judged based on user experience and modeled on Go Experience Reports. These reports should focus on the problems: they should not focus on and need not propose solutions.
What you wanted to do
Manage Authorization configuration and rules outside of the schema
What you actually did
Put Authorization configuration and rules inside of the schema
Why that wasn’t great, with examples
Any external references to support your case
^ Thanks for this link @jdgamble555
they should not focus on and need not propose solutions.
Sorry, can’t really help but to provide this also.
It was talked about moving the Authorization line from the schema to the /admin
GraphQL API.
This would open the door for more advanced control options
- The input schema could be made public without also exposing all authorization rules
- A single rule could be applied to multiple places without rewriting the same rule redundently
- Easier iteration on schema without auth rules taking up so much schema realty
- Admin management (Dgraph Cloud or custom Dgraph management solutions) endpoints could be made to work with these rules independently of schema alterations.
This also paves the way forward for auth rules at the field level as well.
Here is schema I propose to handle all of the above
enum Algo {
HS256
RS256
}
type Auth {
header: String
namespace: String
algo: Algo
verificationKey: String
JWKurl: String
audience: [String]
closedByDefault: Boolean
}
type AuthRule {
id: ID
rule: String
and: [AuthRule]
or: [AuthRule]
not: AuthRule
}
type AuthType {
type: String! @id
password: AuthRule
query: AuthRule
add: AuthRule
update: AuthRule
delete: AuthRule
fields: [AuthField]
}
type AuthField {
id: ID
field: String! @search(by: [hash])
query: AuthRule
mutate: AuthRule
}
This schema proposed should work with the same kind of GraphQL generation that provides the following queries and mutations that are unique to the admin API.
type Query {
getAuth: Auth
getAuthRule(id: ID!): AuthRule
queryAuthRule: [AuthRule]
getAuthType(type: String!): AuthType
queryAuthType(filter: AuthTypeFilter, first: Int, offset: Int): [AuthType]
getAuthField(id: ID!): AuthField
queryAuthField(filter: AuthFieldFilter)
}
type Mutation {
updateAuth(input: AuthPatch): Auth
deleteAuth: Auth
addAuthRule(input: [AddAuthRuleInput!]!): AddAuthRulePayload
updateAuthRule(input: UpdateAuthRuleInput!): UpdateAuthRulePayload
deleteAuthRule(filter: AuthRuleFilter!): DeleteAuthRulePayload
addAuthType(input: [AddAuthTypeInput!]!): AddAuthTypePayload
updateAuthType(input: UpdateAuthTypeInput!): UpdateAuthTypePayload
deleteAuthType(filter: AuthTypeFilter!): DeleteAuthTypePayload
addAuthField(input: [AddAuthFieldInput!]!): AddAuthFieldPayload
updateAuthField(input: UpdateAuthFieldInput!): UpdateAuthFieldPayload
deleteAuthField(filter: AuthFieldFilter!): DeleteAuthFieldPayload
}
input AuthTypeFilter {
type: StringHashFilter
has: AuthRuleHasFilter
and: [AuthRuleFilter]
or: [AuthRuleFilter]
not: AuthRuleFilter
}
enum AuthRuleHasFilter {
password
query
add
update
delete
fields
}
input AuthFieldFilter {
id: [ID!]
field: StringHashFilter
has: AuthFieldHasFilter
and: [AuthFieldFilter]
or: [AuthFieldFilter]
not: AuthFieldFilter
}
enum AuthFieldHasFilter {
query
mutate
}
input AuthPatch {
header: String
namespace: String
algo: Algo
verificationKey: String
JWKurl: String
audience: [String]
closedByDefault: Boolean
}
input AddAuthRuleInput { ... }
type AddAuthRulePayload { ... }
input UpdateAuthRuleInput { ... }
type UpdateAuthRulePayload { ... }
type DeleteAuthRulePayload { ... }
input AddAuthTypeInput { ... }
type AddAuthTypePayload { ... }
input UpdateAuthTypeInput { ... }
type UpdateAuthTypePayload { ... }
type DeleteAuthTypePayload { ... }
input AddAuthFieldInput { ... }
type AddAuthFieldPayload { ... }
input UpdateAuthFieldInput { ... }
type UpdateAuthFieldPayload { ... }
type DeleteAuthFieldPayload { ... }
This got me thinking maybe the entire schema could be held piece by piece in a management graph and then queried and iterated upon in pieces and the functions that generate a more static schema file, could read from this schema graph.
This tangent idea would take the form of AuthType
above, but have information about specific fields. Adding a single field to a type would be then making a mutation to update that one type which would trigger the full API schema rebuild process.