Upgrade to Pro — share decks privately, control downloads, hide ads and more …

flexible-authorization

 flexible-authorization

Flexible Authorization: Storing & Managing Rules in Database presentation for RDRC 2016

Giovanni Sakti

June 23, 2016
Tweet

More Decks by Giovanni Sakti

Other Decks in Programming

Transcript

  1. Storing & Managing Rules in Database
    Flexible Authorization

    View Slide

  2. @giosakti
    Giovanni Sakti

    View Slide

  3. View Slide

  4. Storing & Managing Rules in Database
    Flexible Authorization

    View Slide

  5. Storing & Managing Rules in Database
    Flexible Authorization

    View Slide

  6. Why is flexibility
    necessary?

    View Slide

  7. Why is flexibility
    necessary?
    It’s for future improvement and

    because my blood type is also O

    View Slide

  8. U: Can you make role A able to read this
    document after its state changes to approved?
    Me: *(hack the source code a bit)* Done
    U: Can you make role B release this document
    after at least 5 people agree?
    Me: *(hack the source code a bit)* Done
    U: *(Insert some very specific requests here)*
    Me: *(hack the source code a bit)* Done

    View Slide

  9. U: Can you just give me a nice interfaces to work
    with, so that I don’t have to bug you anymore
    when new requirements appear?

    View Slide

  10. Steps

    View Slide

  11. Regulating
    Collecting
    Evaluating
    Enforcing / Scoping
    Subsystems

    View Slide

  12. Subsystems
    Store rules/regulations/policies
    Regulating
    1
    Can I read this document
    Enforcing /
    Scoping
    2
    3 Evaluating
    4 Collecting

    View Slide

  13. Subsystems
    Store rules/regulations/policies
    Regulating
    1
    Can I read this document
    Enforcing /
    Scoping
    2
    3 Evaluating
    4 Collecting

    View Slide

  14. Subject Who
    Action What
    Object / Resource What
    Environment When, Where, How, Why
    Elements

    View Slide

  15. Regulating

    View Slide

  16. users roles
    activities
    Defining Tables & Columns
    N N
    N
    N
    username
    password
    e-mail
    name
    name
    actions : JSONB
    object
    conditions : JSONB
    Regulating

    View Slide

  17. actions: ['READ'],
    object: 'Document',
    conditions: [
    "object.state = 'APPROVED'"
    ]
    actions: ['RELEASE'],
    object: 'Document',
    conditions: [
    "object.approver_count >= 5"
    ]
    Regulating

    View Slide

  18. actions: ['READ', 'UPDATE', 'DELETE'],
    object: 'Document',
    conditions: [
    "AND",
    "object.organization.code = 'A000'",
    "object.state = 'RELEASED"
    ]
    Regulating

    View Slide

  19. actions: ['READ', 'UPDATE', 'DELETE'],
    object: 'Document',
    conditions: [
    "AND",
    [
    "OR",
    "object.organization.code = 'A000'",
    "object.organization.code = ‘B000'"
    ],
    "object.state = 'RELEASED"
    ]
    Regulating

    View Slide

  20. WYSIWYGish editor
    document organization
    code = ‘A000’
    Live preview
    Regulating

    View Slide

  21. Collecting

    View Slide

  22. # documents_controller.rb
    ...
    def destroy
    authorize @document, :delete?
    @document.destroy!
    render json: @document
    end
    ...
    Collecting

    View Slide

  23. # application_policy.rb
    ...
    activities = @user.active_role.activities.
    where("actions ?? :action", action: "DESTROY").
    where(object: “Document")
    ...
    Collecting

    View Slide

  24. Evaluating

    View Slide

  25. actions: ['READ', 'UPDATE', 'DELETE'],
    object: 'Document',
    conditions: [
    "AND",
    [
    "OR",
    "object.organization.code = 'A000'",
    "object.organization.code = ‘B000'"
    ],
    "object.state = 'RELEASED"
    ]
    Evaluate conditions tree
    Evaluating

    View Slide

  26. Enforcing / Scoping

    View Slide

  27. May I (read/update/approve) this
    document?
    Enforcing

    View Slide

  28. # documents_controller.rb
    ...
    def destroy
    authorize @document, :delete?
    @document.destroy!
    render json: @document
    end
    ...
    Enforcing

    View Slide

  29. What documents can I read?
    Scoping

    View Slide

  30. actions: ['READ', 'UPDATE', 'DELETE'],
    object: 'Document',
    conditions: [
    "AND",
    [
    "OR",
    "object.organization.code = 'A000'",
    "object.organization.code = ‘B000'"
    ],
    "object.state = 'RELEASED"
    ]
    Scoping
    def parse_json(opts = {})
    instruction = {}
    instruction[:joins] = []
    instruction[:selects] = {}
    # If json_arr is blank
    if opts[:json_arr].blank?
    instruction[:query] = TRUE_QUERY
    return instruction
    end
    # If json_arr is not blank
    operator = nil
    operand_stack = []
    opts[:json_arr].each_with_index do |token, idx|
    if (idx == 0) && (%w(AND OR).include? token)
    operator = token
    else
    if token.is_a? Array
    temp = parse_json(opts.merge({json_arr: token}))
    instruction[:joins] |= temp[:joins].flatten
    instruction[:selects].merge! temp[:selects]
    query = "(#{temp[:query]})"
    else
    query_tokens = token.scan(/(?:"(?:\\.|[^"])*"|[^" ])+/)
    if (query_tokens.size != 3) && (!%w(= IN).include? query_tokens[1])
    raise "Syntax error #{token}"
    else
    lhs_join = nil
    lhs_select = nil
    lhs_query = ""
    lhs_arr = query_tokens[0].split(".")
    lhs_arr.to_enum.with_index.reverse_each do |atom, idx|
    if idx == lhs_arr.size - 1
    lhs_query = atom
    lhs_select = {"#{atom}" => lhs_query}
    elsif idx < lhs_arr.size - 1 && idx > 0
    if lhs_join.nil?
    lhs_join = atom.to_sym
    else
    lhs_join = {atom.to_sym => lhs_join}
    end
    lhs_query = "#{atom}.#{lhs_arr[lhs_arr.size - 1]}"
    lhs_select = {"#{lhs_arr[lhs_arr.size - 1]}" => lhs_query}
    else
    # If array size is 2, then we should rename object to avoid ambiguity sql statement
    if lhs_arr.size == 2
    lhs_query = "#{opts[:object].table_name}.#{lhs_arr[lhs_arr.size - 1]}"
    lhs_select = {"#{lhs_arr[lhs_arr.size - 1]}" => lhs_query}
    end
    end
    end
    rhs_query = ""
    if query_tokens[2].start_with? "subject"
    subject_scope = opts[:subject]
    rhs_arr = query_tokens[2].split(".")
    rhs_arr.each_with_index do |atom, idx|
    # If subject is not exist then there is no need to construct query, move along
    unless subject_scope
    rhs_query = ""
    next
    end
    if idx == 0
    # NOP
    elsif idx > 0 && idx < (rhs_arr.size - 1)
    subject_scope = subject_scope.send(atom.to_sym)
    end
    if idx == (rhs_arr.size - 1)
    if query_tokens[1] == "IN"
    values = subject_scope.map{|m| "'#{m.send(atom.to_sym)}'"}
    rhs_query = "(#{values.join(',')})" if values.present?
    else
    rhs_query = "'#{subject_scope.send(atom.to_sym)}'"
    end
    end
    end
    else
    rhs_query = query_tokens[2]
    end
    instruction[:joins] |= [lhs_join] if lhs_join.present?
    instruction[:selects].merge! lhs_select if lhs_select.present?
    if rhs_query.present?
    query = "#{lhs_query} #{query_tokens[1]} #{rhs_query}"
    else
    query = FALSE_QUERY
    end
    end
    end
    operand_stack.push query
    end
    end
    if operator
    instruction[:query] = operand_stack.join(" #{operator} ")
    else
    instruction[:query] = operand_stack.shift
    end
    return instruction
    end
    What to select?
    What to join?
    What to filter?

    View Slide

  31. Challenges &
    Improvements

    View Slide

  32. Performance

    View Slide

  33. Conflict Resolution
    What if there are two or more rules with different outcome

    View Slide

  34. e.g. XACML
    Use Open Standard ?

    View Slide

  35. With the help of oAuth
    Centralized Authorization

    View Slide

  36. Conclusion

    View Slide

  37. 4 subsystems to consider
    regulating, collecting, evaluating, enforcing / scoping

    View Slide

  38. Format for storing authorization rules is important
    That’s why there’s even a standard for this

    View Slide

  39. The current focus is on how to make our
    authorization system less dependent on
    developers and give power to user

    View Slide

  40. Thanks!
    @giosakti
    https://speakerdeck.com/giosakti/flexible-authorization

    View Slide