Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SECURITY.md file #1

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Security Policy for Nubank Open Source Projects

## Supported Versions

Nubank supports the latest version of each of our open-source projects. Once a new version is released, we stop providing patches for security issues in older versions.

## Reporting Security Issues

Your efforts to responsibly disclose your findings are sincerely appreciated and will be taken into account to acknowledge your contributions.
If you discover a vulnerability, please do the following:

1. E-mail your findings to [security@nubank.com.br](mailto:security@nubank.com.br). If the issue is sensitive, please use [our PGP key](https://nubank.com.br/.well-known/security.txt) to encrypt your communications with us.
2. Do not take advantage of the vulnerability or problem you have discovered.
3. Do not reveal the problem to others until it has been resolved.
4. Provide sufficient information to reproduce the problem so we can resolve it as quickly as possible.
5. You will receive a response from us acknowledging receipt of your vulnerability report.
6. You'll receive regular updates about our progress.
7. Once the issue is resolved, we would like to mention your name in any dispatches about the issue so that we can credit you for your discovery. Please engage in responsible privacy practices when disclosing bugs to us, and we'll handle each report with utmost urgency.

## Preferred Languages

We prefer all communications to be in English.

## Policy Adherence

We greatly value your assistance in discovering and reporting vulnerabilities, and look forward to working with users who wish to help ensure Nubank's open-source projects' safety and security. Thank you for supporting Nubank's mission and helping ensure the highest levels of security for our community!
17 changes: 13 additions & 4 deletions examples/config/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@ provider "opsgenie" {
}

locals {
# Build a map of our various Opsgenie resources that will be used to iterate over each module
opsgenie_resources = merge([
for resource_file in fileset(path.cwd, "resources/*.yaml") : {
# load the config for each squad individually
# Temporary variable to hold the config for each squad
squads_configs = [
for resource_file in fileset(path.cwd, "squads/*/*.yaml") : {
for k, v in yamldecode(file(resource_file)) : k => v
}
]...)
]

# Build a map of our various Opsgenie resources that will be used to iterate over each module
# by "joining" the configs from many squads into a single map
opsgenie_resources = {
for key in distinct(flatten([for x in local.squads_configs : keys(x)])) :
key => flatten([
for m, n in local.squads_configs : n[key] if keys(n)[0] == key])
}
}

module "opsgenie_config" {
Expand Down
8 changes: 4 additions & 4 deletions modules/config/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## Config

Terraform module that configures a multitude of [Opsgenie resources](https://registry.terraform.io/providers/opsgenie/opsgenie/latest/docs).
Terraform module that configures a multitude of [Opsgenie resources](https://registry.terraform.io/providers/opsgenie/opsgenie/latest/docs).
Many resources have cross-resource dependencies, which may be simpler to handle within a single module in certain cases, such as using YAML configurations.

This module is designed to accept an input configuration map.
One nice way of handling this is by passing resource definitions from a YAML configuration file.
This module is designed to accept an input configuration map.
One nice way of handling this is by passing resource definitions from a YAML configuration file.

See below for details & examples.

Expand Down Expand Up @@ -50,7 +50,7 @@ escalations:
condition: if-not-acked
notify_type: default
delay: 0
recipients:
recipient:
- type: team
team_name: acme.dev.some-service
```
Expand Down
22 changes: 9 additions & 13 deletions modules/config/escalations.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,18 @@ resource "opsgenie_escalation" "this" {
notify_type = try(rules.value.notify_type, "default")
delay = try(rules.value.delay, 0)

dynamic "recipient" {
for_each = try(rules.value.recipients, [])

content {
type = recipient.value.type

id = lookup(recipient.value, "id", null) != null ? recipient.value.id : (
recipient.value.type == "team" ? opsgenie_team.this[recipient.value.team_name].id : (
recipient.value.type == "user" ? try(opsgenie_user.this[recipient.value.user_name].id, data.opsgenie_user.this[recipient.value.user_name].id) : (
recipient.value.type == "schedule" ? opsgenie_schedule.this[recipient.value.schedule_name].id : (
null
)
recipient {
type = rules.value.recipient.type

id = lookup(rules.value.recipient, "id", null) != null ? rules.value.recipient.id : (
rules.value.recipient.type == "team" ? try(opsgenie_team.this[rules.value.recipient.team_name].id, data.opsgenie_team.this[rules.value.recipient.team_name].id) : (
rules.value.recipient.type == "user" ? try(opsgenie_user.this[rules.value.recipient.user_name].id, data.opsgenie_user.this[rules.value.recipient.user_name].id) : (
rules.value.recipient.type == "schedule" ? try(opsgenie_schedule.this[rules.value.recipient.schedule_name].id, data.opsgenie_schedule.this[rules.value.recipient.schedule_name].id) : (
null
)
)
)
}
)
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions modules/config/existing_resources.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// local.existing users is a list of key pairs, in which all keys are "username".
// I want to remove duplicated items from the list based on the value of each item.
locals {
distinct_existing_users = distinct([for user in local.existing_users : user.username])
unique_existing_users = [for u in local.distinct_existing_users : { "username" = u }]

unique_existing_schedules = distinct(local.existing_schedules)

unique_existing_teams = distinct(local.existing_teams)
}

data "opsgenie_user" "this" {
for_each = module.this.enabled ? { for user in local.unique_existing_users : user.username => user } : tomap()

username = each.value.username
}

data "opsgenie_schedule" "this" {
for_each = module.this.enabled ? toset(local.unique_existing_schedules) : toset()

name = each.key
}

data "opsgenie_team" "this" {
for_each = module.this.enabled ? toset(local.unique_existing_teams) : toset()

name = each.key
}
5 changes: 0 additions & 5 deletions modules/config/existing_users.tf

This file was deleted.

2 changes: 2 additions & 0 deletions modules/config/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ locals {
integration_actions = lookup(var.opsgenie_resources, "integration_actions", [])
notification_policies = lookup(var.opsgenie_resources, "notification_policies", [])
schedules = lookup(var.opsgenie_resources, "schedules", [])
existing_schedules = lookup(var.opsgenie_resources, "existing_schedules", [])
schedule_rotations = lookup(var.opsgenie_resources, "schedule_rotations", [])
team_routing_rules = lookup(var.opsgenie_resources, "team_routing_rules", [])
teams = lookup(var.opsgenie_resources, "teams", [])
existing_teams = lookup(var.opsgenie_resources, "existing_teams", [])
users = lookup(var.opsgenie_resources, "users", [])
existing_users = lookup(var.opsgenie_resources, "existing_users", [])
services = lookup(var.opsgenie_resources, "services", [])
Expand Down
108 changes: 99 additions & 9 deletions modules/config/notification_policies.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ resource "opsgenie_notification_policy" "this" {
for_each = module.this.enabled ? { for policy in local.notification_policies : policy.name => policy } : tomap()

enabled = try(each.value.enabled, true)
name = each.value.name
name = each.key

# Look up our team id by name
team_id = opsgenie_team.this[each.value.team_name].id
Expand All @@ -15,20 +15,110 @@ resource "opsgenie_notification_policy" "this" {
for_each = try(each.value.filter.conditions, [])

content {
expected_value = try(conditions.value.expected_value, null)
field = try(conditions.value.field, null)
field = conditions.value.field
operation = conditions.value.operation
expected_value = try(conditions.value.expected_value, "")
key = try(conditions.value.key, null)
not = try(conditions.value.not, null)
operation = try(conditions.value.operation, null)
not = try(conditions.value.not, false)
order = try(conditions.value.order, null)
}
}
}

auto_close_action {
duration {
time_amount = try(each.value.auto_close_action.time_amount, null)
time_unit = try(each.value.auto_close_action.time_unit, "minutes")
dynamic "time_restriction" {
for_each = try(each.value.time_restriction, null) != null ? [each.value.time_restriction] : []

content {
type = time_restriction.value.type

dynamic "restrictions" {
for_each = try(time_restriction.value.restrictions, null) != null ? [time_restriction.value.restrictions] : []

content {
start_day = restrictions.value.start_day
end_day = restrictions.value.end_day
start_hour = restrictions.value.start_hour
end_hour = restrictions.value.end_hour
start_min = restrictions.value.start_min
end_min = restrictions.value.end_min
}
}

dynamic "restriction" {
for_each = try(time_restriction.value.restriction, null) != null ? [time_restriction.value.restriction] : []

content {
start_hour = restriction.value.start_hour
end_hour = restriction.value.end_hour
start_min = restriction.value.start_min
end_min = restriction.value.end_min
}
}
}
}

dynamic "auto_close_action" {
for_each = try(each.value.auto_close_action, null) != null ? [each.value.auto_close_action] : []

content {
duration {
time_amount = auto_close_action.value.duration.time_amount
time_unit = try(auto_close_action.value.duration.time_unit, "minutes")
}
}

}

dynamic "auto_restart_action" {
for_each = try(each.value.auto_restart_action, null) != null ? [each.value.auto_restart_action] : []

content {
duration {
time_amount = auto_restart_action.value.duration.time_amount
time_unit = try(auto_restart_action.value.duration.time_unit, "minutes")
}
max_repeat_count = auto_restart_action.value.max_repeat_count
}

}

dynamic "de_duplication_action" {
for_each = try(each.value.de_duplication_action, null) != null ? [each.value.de_duplication_action] : []

content {
de_duplication_action_type = de_duplication_action.value.de_duplication_action_type
count = de_duplication_action.value.count

dynamic "duration" {
for_each = each.value.de_duplication_action.de_duplication_action_type == "frequency-based" ? [each.value.de_duplication_action.duration] : [try(each.value.de_duplication_action.duration, null)]

content {
time_amount = duration.value.time_amount
time_unit = try(duration.value.time_unit, "minutes")
}
}
}
}

dynamic "delay_action" {
for_each = try(each.value.delay_action, null) != null ? [each.value.delay_action] : []

content {
delay_option = delay_action.value.delay_option

dynamic "duration" {
for_each = delay_action.value.delay_option == "for-duration" ? [delay_action.value.duration] : []

content {
time_amount = duration.value.time_amount
time_unit = try(duration.valeu.time_unit, "minutes")
}
}

until_hour = delay_action.value.delay_option != "for-duration" ? delay_action.value.until_hour : null
until_minute = delay_action.value.delay_option != "for-duration" ? delay_action.value.until_minute : null
}
}

suppress = try(each.value.suppress, null)
}
2 changes: 1 addition & 1 deletion modules/config/schedule_rotations.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ resource "opsgenie_schedule_rotation" "this" {

content {
type = participant.value.type
id = try(opsgenie_user.this[participant.value.username].id, data.opsgenie_user.this[participant.value.username].id)
id = participant.value.type == "none" ? null : try(opsgenie_user.this[participant.value.username].id, data.opsgenie_user.this[participant.value.username].id)
}
}

Expand Down
19 changes: 18 additions & 1 deletion modules/notification_policy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ module "notification_policy" {
}]
}

de_duplication_action = {
de_duplication_action_type = "frequency-based"
count = 2
duration = {
time_unit = "minutes"
time_amount = 5
}
}

delay_action = {
delay_option = "for-duration"
duration = {
time_unit = "minutes"
time_amount = 10
}
}

auto_close_action = {
time_unit = "minutes"
time_amount = 5
Expand All @@ -36,7 +53,7 @@ module "notification_policy" {

## Inputs

**Note:** `notification_policy` is a map for two reasons:
**Note:** `notification_policy` is a map for two reasons:
- to be able to put whole configuration in yaml file
- variables defined with type set are not robust enough (can't set default values)

Expand Down
Loading