Политики предоставляют декларативный способ предоставления или запрета доступа к определённым путям и операциям в Stronghold. В этом разделе рассматриваются связанные с политиками процессы и их синтаксис.

По умолчанию политики работают по принципу запрета, поэтому пустая политика не предоставляет никаких прав в системе.

Процесс аутентификации на основе политики

Прежде чем человек или машина смогут получить доступ, администратор должен настроить Stronghold с помощью одного из методов аутентификации. Аутентификация — это процесс, при котором предоставленная человеком или машиной информация проверяется на подлинность внутренней или внешней системой.

Рассмотрим процесс с описанием шагов, которые должна выполнить команда безопасности для настройки аутентификации в Stronghold с использованием корпоративной службы LDAP или Active Directory. Несмотря на то, что в примере используется LDAP, этот подход применим ко всем методам аутентификации.

  1. Команда безопасности настраивает Stronghold для подключения к выбранному методу аутентификации. У каждого метода аутентификации свои настройки. В случае с LDAP Stronghold необходимо знать адрес сервера LDAP, а также следует ли подключаться с использованием TLS. Важно отметить, что Stronghold не хранит копию базы данных LDAP. Stronghold делегирует аутентификацию выбранному методу аутентификации.

  2. Команда безопасности создаёт политику (или использует уже существующую), которая предоставляет доступ к путям в Stronghold. Политики составляются на языке HCL в любом текстовом редакторе и сохраняются на диске.

  3. Содержимое политики подгружается и сохраняется в Stronghold, после чего за политикой закрепляется определённое имя. Имя политики следует рассматривать как указатель или символьную ссылку на соответствующий набор правил.

  4. На самом важном этапе команда безопасности сопоставляет данные метода аутентификации с политикой. Например, команда безопасности может создавать следующие сопоставления (mappings):

    • Члены группы OU «dev» сопоставляются с политикой Stronghold под именем «readonly-dev».
    • Члены группы OU «ops» сопоставляются с политиками Stronghold под именами «admin» и «auditor».

В результате в Stronghold появляется внутреннее сопоставление между системой аутентификации бэкенда и внутренней политикой. Когда пользователь проходит аутентификацию в Stronghold, процесс аутентификации делегируется выбранному методу аутентификации.

Для пользователя процесс аутентификации выглядит следующим образом:

  1. Пользователь пытается пройти аутентификацию, используя свои учетные данные LDAP, предоставляя Stronghold своё имя пользователя и пароль.

  2. Stronghold соединяется со службой LDAP и просит сервер подтвердить подлинность предоставленных учетных данных. После успешного подтверждения сервер LDAP возвращает информацию о пользователе, включая группы OU.

  3. Stronghold сопоставляет результат, полученный от сервера LDAP, с политиками, используя настройки сопоставления, ранее заданные командой безопасности. Затем Stronghold генерирует токен и прикрепляет соответствующие политики.

  4. Stronghold возвращает токен пользователю. За этим токеном закреплены необходимые политики в соответствии с настройками сопоставления, ранее заданными командой безопасности.

  5. Пользователь использует этот токен Stronghold для будущих операций. При повторном выполнении шагов аутентификации пользователь получит новый токен. При этом новый токен будет иметь те же права, но фактически это будет уже другой токен. Повторная аутентификация не приведёт к инвалидации исходного токена.

Синтаксис политик

Политики пишутся на языке HCL или JSON и описывают, к каким путям в Stronghold пользователю или машине разрешен доступ.

Пример простой политики, предоставляющей доступ для чтения данных по пути secret/foo в KV/v1:

path "secret/foo" {
  capabilities = ["read"]
}

При назначении этой политики токен сможет читать данные из secret/foo. Однако токен не сможет обновить или удалить secret/foo, поскольку не предоставлены соответствующие возможности (capabilities). Поскольку по умолчанию политики работают по принципу запрета, у токена не будет других доступов в Stronghold.

Пример более подробной политики с комментариями:

# В данном разделе предоставляется полный доступ к "secret/*".
# К этой широкой политике могут быть применены дополнительные ограничения, как показано ниже.
path "secret/*" {
  capabilities = ["create", "read", "update", "patch", "delete", "list"]
}

# Несмотря на то, что мы разрешили доступ к "secret/*", эта строка явно запрещает доступ к "secret/super-secret".
# У этого запрета больший приоритет.
path "secret/super-secret" {
  capabilities = ["deny"]
}

# Политики также могут указывать разрешенные, запрещённые и обязательные параметры.
# Здесь ключ "secret/restricted" может содержать только "foo" (любое значение) и "bar" ("zip" или "zap").
path "secret/restricted" {
  capabilities = ["create"]
  allowed_parameters = {
    "foo" = []
    "bar" = ["zip", "zap"]
  }
}

При обработке запроса политики используют сопоставление на основе путей для проверки набора возможностей. В пути политики может быть указан точный путь для сопоставления или особая маска, которая предписывает Stronghold использовать сопоставление на основе префикса:

# Разрешить доступ для чтения только к "secret/foo".
# Закреплённый токен не сможет прочитать данные из "secret/food" или "secret/foo/bar".
path "secret/foo" {
  capabilities = ["read"]
}

# Разрешить доступ для чтения всех данных в "secret/bar".
# Закреплённый токен сможет прочитать данные из "secret/bar/zip", "secret/bar/zip/zap", но не из "secret/bars/zip".
path "secret/bar/*" {
  capabilities = ["read"]
}

# Разрешить доступ для чтения всех данных с префиксом "zip-".
# Закреплённый токен сможет прочитать данные из "secret/zip-zap" или "secret/zip-zap/zong", но не из "secret/zip/zap".
path "secret/zip-*" {
  capabilities = ["read"]
}

Символ + (плюс) можно использовать для обозначения любого количества символов в одном из сегментов пути:

# Разрешить доступ для чтения данных по пути "teamb" в любом верхнем сегменте в "secret/".
path "secret/+/teamb" {
  capabilities = ["read"]
}

# Разрешить доступ для чтения данных в "secret/foo/bar/teamb", "secret/bar/foo/teamb" и т. д.
path "secret/+/+/teamb" {
  capabilities = ["read"]
}

Архитектура Stronghold похожа на файловую систему. Каждому действию соответствует определённый путь и возможность (capability). Даже внутренние эндпоинты конфигурации ядра Stronghold находятся по пути sys/. Политики определяют доступ к этим путям и возможностям, которые в свою очередь контролируют доступ токенов к учетным данным в Stronghold.

Правила политик, применяемых в Stronghold, определяются наиболее точным доступным совпадением на основе описанных далее правил приоритета. Это может быть точное соответствие или совпадение наиболее длинного префикса по маске. Если в нескольких политиках присутствует одна и та же комбинация, применяется группа возможностей. Если в применимых политиках используются разные комбинации, применяется только совпадение с наивысшим приоритетом из этих политик.

Таким образом, если вы определяете политику для secret/foo*, под эту политику будет также подпадать secret/foobar.

Упоминаемый в документации символ маски — это звездочка (*). Она не является регулярным выражением и поддерживается только если используется на конце пути.

При предоставлении возможности выполнения операций со списками (list) важно помнить, что, поскольку такие операции всегда работают с префиксами, политики должны также работать с префиксами, поскольку Stronghold нормализует пути запросов, приводя их к форме префиксов.

Возможности

Каждый путь должен определять одну или несколько возможностей, которые обеспечивают тонкий контроль над разрешёнными (или запрещёнными) операциями. Как показано в примерах выше, возможности всегда указываются в виде списка строк, даже если существует только одна возможность.

Чтобы определить возможности, необходимые для выполнения конкретной операции, к подкоманде CLI можно добавить флаг -output-policy.

Список доступных возможностей:

  • create (POST/PUT) — позволяет создавать данные по заданному пути. Лишь немногие компоненты Stronghold могут отличить создание от обновления данных, поэтому для большинства операций требуются возможности как создания, так и обновления.
  • read (GET) — позволяет читать данные по заданному пути.
  • update (POST/PUT) — позволяет изменять данные по заданному пути. Для большинства компонентов Stronghold это неявно включает возможность создания начального значения по заданному пути.
  • patch (PATCH) — позволяет частично обновлять данные по заданному пути.
  • delete (DELETE) — позволяет удалять данные по заданному пути.
  • list (LIST) — позволяет выполнять операции со списками значений по заданному пути. Обратите внимание, что ключи, возвращаемые операцией list, не фильтруются политиками. Не используйте конфиденциальную информацию в именах ключей. Не все бэкенды поддерживают операции со списками.

Напротив каждой возможности в списке выше в скобках указаны названия соответствующих HTTP-методов. При работе с политиками бывает полезно ознакомиться с документацией HTTP API для путей и методами, чтобы сопоставить их с возможностями. Хотя это и не строгое сопоставление, часто возможности совпадают с методами.

В дополнение к стандартным возможностям существует несколько возможностей, которым не соответствует ни один HTTP-метод:

  • sudo — разрешает доступ к путям, защищённым правами root. Токенам не разрешается взаимодействовать с этими путями, если у них нет возможности sudo (в дополнение к другим возможностям, необходимым для выполнения операций по этому пути, таким как чтение или удаление).

    Например, для изменения бэкендов журнала аудита требуется токен с привилегиями sudo.

  • deny — запрещает доступ. У этой возможности всегда наивысший приоритет, независимо от любых других определенных возможностей, включая sudo.

Возможности обычно сопоставляются с соответствующим HTTP-методом, а не с выполняемым действием. Часто это приводит к путанице. Например, операция генерации учётных данных базы данных действительно создаёт эти учётные данные, однако при этом HTTP-запрос использует метод GET, что соответствует возможности чтения (read). Таким образом, чтобы разрешить генерацию учётных данных базы данных, политика должна предоставлять доступ на чтение к соответствующему пути.

Шаблонные политики

Синтаксис политик позволяет подставлять переменные в некоторых строках с использованием значений, доступных токену. В настоящее время можно внедрять информацию об идентификаторах, а также использовать подстановку в ключах путей внутри политик.

Параметры

Имя Описание
identity.entity.id Идентификатор сущности
identity.entity.name Имя сущности
identity.entity.metadata.<metadata key> Метаданные, связанные с сущностью по указанному ключу
identity.entity.aliases.<mount accessor>.id Идентификатор псевдонима сущности для указанного бэкенда аутентификации
identity.entity.aliases.<mount accessor>.name Имя псевдонима сущности для указанного бэкенда аутентификации
identity.entity.aliases.<mount accessor>.metadata.<metadata key> Метаданные, связанные с псевдонимом для указанного бэкенда аутентификации и ключа метаданных
identity.entity.aliases.<mount accessor>.custom_metadata.<custom_metadata key> Кастомные метаданные, связанные с псевдонимом для указанного бэкенда аутентификации и ключа кастомных метаданных
identity.groups.ids.<group id>.name Имя группы для указанного идентификатора группы
identity.groups.names.<group name>.id Идентификатор группы для указанного имени группы
identity.groups.ids.<group id>.metadata.<metadata key> Метаданные, связанные с указанным идентификатором группы по указанному ключу
identity.groups.names.<group name>.metadata.<metadata key> Метаданные, связанные с указанным именем группы по указанному ключу

Примеры

Следующая политика создаёт раздел механизма секретов KV/v2 для определённого пользователя:

path "secret/data//*" {
  capabilities = ["create", "update", "patch", "read", "delete"]
}

path "secret/metadata//*" {
  capabilities = ["list"]
}

Создание общего раздела KV, связанного с сущностями в группе.

# В данном примере идентификатор группы сопоставляет группу с путём.
path "secret/data/groups//*" {
  capabilities = ["create", "update", "patch", "read", "delete"]
}

path "secret/metadata/groups//*" {
  capabilities = ["list"]
}

При разработке шаблонных политик по возможности всегда используйте идентификаторы. Каждому пользователю присвоен уникальный идентификатор, в то время как имена могут со временем измениться и использоваться повторно. Идентификатор гарантирует, что при изменении имени пользователя или группы политика будет сопоставлена с требуемой сущностью или группой.

Если вам понадобится использовать метаданные, связанные с плагином аутентификации, в своих шаблонах, необходимо сперва узнать идентификатор бэкенда аутентификации (mount accessor) и обратиться к нему через ключ псевдонима.

Чтобы узнать идентификатор бэкенда аутентификации, используйте следующую команду:

d8 stronghold auth list

Пример вывода:

Path           Type          Accessor                    Description
----           ----          --------                    -----------
kubernetes/    kubernetes    auth_kubernetes_xxxx        n/a
token/         token         auth_token_yyyy             token based credentials

Следующая шаблонная политика позволяет читать путь, связанный с пространством имён учетной записи Kubernetes идентификатора:

path "secret/data//*" {
  capabilities = ["read"]
}

Тонкая настройка управления доступом

В дополнение к стандартному набору возможностей Stronghold предлагает более тонкий контроль над управлением доступом по определённому пути. Возможности, связанные с настройкой путей, имеют приоритет перед настройками доступа к параметрам.

Ограничения параметров

  • Использование маски (*) может привести к неожиданному поведению.
  • Поля allowed_parameters, denied_parameters и required_parameters не поддерживаются политиками, которые используются с механизмом секретов KV/v2.

Политики могут учитывать параметры HTTP-запросов для дополнительных ограничений запросов при использовании следующих опций:

  • required_parameters — список обязательных параметров.

    # Пользователь должен создать "secret/profile" с параметром/ключом с именем "name" и "id",
    # где KV/v1 включен по пути "secret/".
    path "secret/profile" {
      capabilities = ["create"]
      required_parameters = ["name", "id"]
    }
    
  • allowed_parameters — список допустимых ключей и значений для указанного пути.

    Задание параметру значения из пустого списка позволяет параметру содержать любое значение.

    # Это позволяет пользователю обновить значение параметра пароля, установленное для любого
    # пользователя, настроенного на аутентификации через userpass. Значение пароля может быть любым.
    # Однако пользователь не может обновлять значения других параметров, таких как
    # "token_ttl".
    path "auth/userpass/users/*" {
      capabilities = ["update"]
      allowed_parameters = {
        "password" = []
      }
    }
    

    Установка параметра со значением из заполненного списка позволяет параметру содержать только указанные значения.

    # Это позволяет пользователю создавать или обновлять ключ шифрования для
    # механизма секретов Transit по адресу "transit/". При этом вы можете установить
    # значение параметра "auto_rotate_period" для ротации ключей.
    # Период ротации должен быть равен "8h", "24h" или "5d".
    # Любое другое значение приведет к ошибке.
      
    path "transit/keys/*" {
      capabilities = ["create", "update"]
      allowed_parameters = {
        "auto_rotate_period" = ["8h", "24h", "5d"]
      }
    }
    

    Если указаны какие-либо ключи, все неуказанные параметры будут запрещены, за исключением случая, когда параметр * установлен в пустой массив, что позволит изменять все остальные параметры. Параметры с определёнными значениями будут по-прежнему ограничены этими значениями.

    # Когда в "secret/" включен механизм секретов KV/v1, это позволяет пользователю
    # создавать "secret/foo" с параметром "bar". Параметр "bar" может
    # содержать только значения "zip" или "zap", но любые другие параметры могут быть
    # но любые другие параметры могут быть созданы с любым значением.
    path "secret/foo" {
      capabilities = ["create"]
      allowed_parameters = {
        "bar" = ["zip", "zap"]
        "*"   = []
      }
    }
    
  • denied_parameters — список ключей и значений, которые не разрешены для данного пути. Любые значения, указанные здесь, имеют приоритет над allowed_parameters.

    Установка параметра со значением из пустого списка запрещает любые изменения этого параметра.

    # Это позволяет пользователю обновлять настройки метода аутентификации userpass
    # (например, "пароль"), кроме значений параметров "token_policies"
    # и "policies".
      
    path "auth/userpass/users/*" {
      capabilities = ["update"]
      denied_parameters = {
        "token_policies" = []
        "policies" = []
      }
    }
    

    Установка параметра со значением из заполненного списка запрещает любые параметры, содержащие эти значения.

    # Это позволяет пользователю создавать или обновлять роли токенов.
    # При этом значение параметра "allowed_policies" не может быть "admin",
    # но пользователь может назначать любые другие политики данному параметру.
    path "auth/token/roles/*" {
      capabilities = ["create", "update"]
      denied_parameters = {
        "allowed_policies" = ["admin"]
      }
    }
    

    Если задано значение *, будут запрещены все параметры.

    # Это позволяет пользователю создавать или обновлять ключ шифрования для
    # механизма секретов Transit по адресу "transit/". Однако он не может
    # задать ни один из параметров настройки. В результате
    # все параметры созданного ключа будут иметь значения по умолчанию.
    path "transit/keys/*" {
      capabilities = ["create", "update"]
      denied_parameters = {
        "*" = []
      }
    }
    

    Если указаны какие-либо параметры, все неуказанные параметры разрешены, если только не задан параметр allowed_parameters. В этом случае работают обычные правила.

В значениях параметров допускается использовать маску в префиксах и суффиксах. Маска включается путём добавления символа * к значению префикса или суффикса:

# Разрешён только параметр с именем "bar" со значением, начинающимся с "foo-*".
path "secret/foo" {
  capabilities = ["create"]
  allowed_parameters = {
    "bar" = ["foo-*"]
  }
}

С параметром * допускается использовать только значение [].

Значения по умолчанию

Оценка политик с указанными allowed_parameters, denied_parameters, и required_parameters происходит без учёта значений параметров по умолчанию.

Рассмотрим следующую политику:

# Для параметра "no_store" не может быть установлено значение "false".
path "secret/foo" {
  capabilities = ["create"]
  denied_parameters = {
    "no_store" = [false, "false"]
  }
}

Следующая операция завершится ошибкой, поскольку для параметра no_store установлено значение false:

d8 stronghold write secret/foo no_store=false value=bar

В то время как следующая операция будет выполнена, даже если параметр no_store должен быть булевым, а его значение по умолчанию равно false:

# Команда будет выполнена, потому что параметры не содержат "no_store=false".
d8 stronghold write secret/foo value=bar

Это происходит потому, что анализатор политики не знает, какое значение по умолчанию установлено для параметра no_store. Он видит только то, что запрещённого параметра нет в команде.

Эту проблему можно решить, указав параметр no_store в политике как обязательный:

path "secret/foo" {
  capabilities = ["create"]
  required_parameters = ["no_store"]
  denied_parameters = {
    "no_store" = [false, "false"]
  }
}

Следующая команда, которая ранее выполнялась без ошибок, теперь не будет выполнена в соответствии с новой политикой, поскольку в ней отсутствует параметр no_store:

d8 stronghold write secret/foo value=bar

Использование маски

Важно отметить, что использование маски может привести к неожиданному поведению:

# Этот пример позволяет пользователю создавать, обновлять или изменять путь "secret/foo"
# с параметром под именем "bar". Значения, передаваемые параметру "bar", должны начинаться с "baz/",
# поэтому значения вроде "baz/quux" будут допустимы. Однако значения вроде
# "baz/quux,wibble,wobble,wubble" тоже будут приняты. API, лежащий в основе "secret/foo",
# может поддерживать перечисление нескольких значений для параметра "bar" через запятую.
# В таком случае указание значения "baz/quux,wibble,wobble,wubble" приведёт к тому, что
# будут переданы четыре отдельных значения. Увидеть, что к "secret/foo" попали значения вроде
# "wibble" или "wobble", может быть неожиданно для того, кто рассчитывал, что ограничение
# "allowed_parameters" допускает только значения, начинающиеся с "baz/".
path "secret/foo" {
  capabilities = ["create", "update", "patch"]
  allowed_parameters = {
    "bar" = ["baz/*"]
  }
}

Требуемые TTL для обёртывания ответа

Эти параметры можно использовать для установки минимальных и максимальных значений TTL, задаваемых клиентами при запросе на обёртывание ответа, с точностью до секунды. Они используют строки формата duration.

На практике установка минимального TTL в одну секунду делает оборачивание ответа обязательным для определенного пути.

  • min_wrapping_ttl — минимально допустимый TTL, который клиенты могут указать для обёрнутого ответа. На практике установка минимального TTL в одну секунду фактически делает оборачивание ответа обязательным для конкретного пути. Это также может использоваться для обеспечения того, чтобы TTL не был слишком низким, что приведет к тому, что конечные цели не смогут развернуть ответ до истечения срока действия токена.
  • max_wrapping_ttl — максимально допустимый TTL, который клиенты могут указать для обёрнутого ответа.
# Установка для параметра "min_wrapping_ttl" значения в 1 секунду делает оборачивание ответа обязательным для данного пути.
# Также здесь устанавливается максимально допустимый TTL для обёрнутого ответа по указанному пути в 90 секунд.
path "auth/approle/role/my-role/secret-id" {
    capabilities = ["create", "update"]
    min_wrapping_ttl = "1s"
    max_wrapping_ttl = "90s"
}

Если указаны оба параметра, минимальное значение должно быть меньше максимального. Кроме того, если пути объединяются из строк нескольких конфигураций, будет использовано минимальное указанное значение для каждой из них — по принципу использования наименьшего возможного TTL для токенов.

Встроенные политики

В Stronghold есть две встроенные политики: политика по умолчанию и root-политика. В этом разделе описываются две встроенные политики.

Политика по умолчанию

Политика по умолчанию — это встроенная политика Stronghold, которую нельзя удалить. По умолчанию она привязывается ко всем токенам, но может быть явно исключена во время создания токена с помощью поддерживаемых методов аутентификации.

Политика содержит базовую функциональность, такую как возможность для токена искать данные о себе и использовать данные из cubbyhole. Однако Stronghold не накладывает жёстких ограничений на её содержимое — политику можно изменять в соответствии с вашими потребностями, и Stronghold никогда не перезапишет ваши изменения. Если вы хотите синхронизировать её с последней версией политики по умолчанию из исходного проекта, прочитайте содержимое политики на актуальном dev-сервере и запишите его в политику Stronghold по умолчанию.

Чтобы просмотреть все разрешения, предоставленные политикой по умолчанию для вашего экземпляра Stronghold, выполните следующую команду:

d8 stronghold read sys/policy/default

Чтобы отключить прикрепление политики по умолчанию, выполните следующую команду:

d8 stronghold token create -no-default-policy

Или используйте API:

curl \
  --request POST \
  --header "X-Vault-Token: ..." \
  --data '{"no_default_policy": "true"}' \
  https://stronghold.example.com/v1/auth/token/create

Root-политика

Root-политика — это встроенная политика Stronghold, которую нельзя изменить или удалить. Любой пользователь, связанный с этой политикой, становится root-пользователем. Root-пользователю доступны любые действия в Stronghold. Поэтому настоятельно рекомендуется отозвать все root-токены перед использованием Stronghold в production-средах.

При первой инициализации сервера Stronghold всегда существует один root-пользователь. Этот пользователь используется для первоначальной настройки и подготовки Stronghold. После завершения настройки следует отозвать изначальный root-токен и использовать более строгий контроль за пользователями и аутентификацией.

Чтобы отозвать root-токен, выполните следующую команду:

d8 stronghold token revoke "<token>"

Или используйте API:

curl \
  --request POST \
  --header "X-Vault-Token: ..." \
  --data '{"token": "<token>"}' \
  https://stronghold.example.com/v1/auth/token/revoke

Управление политиками

Для написания политик можно использовать любой текстовый редактор. Они могут быть написаны с помощью языка HCL или JSON. Синтаксис подробно описан выше. После сохранения и перед использованием политики должны быть подгружены в Stronghold.

Вывод списка политик

Чтобы вывести список всех зарегистрированных политик в Stronghold:

d8 stronghold read sys/policy

Или используйте API:

curl \
  --header "X-Vault-Token: ..." \
  https://stronghold.example.com/v1/sys/policy

Создание политик

Политики могут быть созданы (подгружены) через CLI-интерфейс или API. Чтобы создать новую политику в Stronghold, используйте следующую команду:

d8 stronghold policy write policy-name policy-file.hcl

Или используйте API:

curl \
  --request POST \
  --header "X-Vault-Token: ..." \
  --data '{"policy":"path \"...\" {...} "}' \
  https://stronghold.example.com/v1/sys/policy/policy-name

В обоих примерах имя политики — policy-name. Это имя можно рассматривать как указатель или символьную ссылку на ACL политики. Токены прикрепляются к политике по имени, которое затем сопоставляется с набором правил, соответствующих этому имени.

Обновление политик

Существующие политики можно обновлять через CLI-интерфейс или API для изменения уровней доступа. Чтобы обновить существующую политику в Stronghold, выполните те же действия, что и при создании политики, но при этом используйте имя существующей политики:

d8 stronghold write sys/policy/my-existing-policy policy=@updated-policy.json

Или используйте API:

curl \
  --request POST \
  --header "X-Vault-Token: ..." \
  --data '{"policy":"path \"...\" {...} "}' \
  https://stronghold.example.com/v1/sys/policy/my-existing-policy

Удаление политик

Существующие политики можно удалять через CLI-интерфейс или API. Чтобы удалить политику, используйте следующую команду:

d8 stronghold delete sys/policy/policy-name

Или используйте API:

curl \
  --request DELETE \
  --header "X-Vault-Token: ..." \
  https://stronghold.example.com/v1/sys/policy/policy-name

Это идемпотентная операция. Stronghold не вернёт ошибку при попытке удаления несуществующей политики.

Прикрепление политик

Stronghold может автоматически прикреплять набор политик к токену на основе авторизации. Эта конфигурация существенно различается в различных бэкендах аутентификации. Для наглядности в этом примере будет рассмотрен встроенный в Stronghold метод аутентификации Userpass.

  1. Администратор Stronghold или член команды безопасности создаёт пользователя со списком привязанных политик:

    d8 stronghold write auth/userpass/users/sethvargo \
        password="s3cr3t!" \
        policies="dev-readonly,logs"
    
  2. Это запустит процесс сопоставления аутентификации с политикой, который приведёт к тому, что при успешной аутентификации пользователя в Stronghold пользователю будет выдан токен со списком привязанных политик.

  3. Пользователь, желающий пройти аутентификацию, выполняет следующую команду:

    d8 stronghold login -method="userpass" username="sethvargo"
    Password: ...
    
  4. Если предоставленная информация верна, Stronghold сгенерирует токен, присвоит ему список настроенных политик и вернёт этот токен аутентифицированному пользователю.

API-эндпоинты с root-защитой

Stronghold рассматривает HTTP-методы POST и PUT как равные, поэтому для каждого упоминания POST в таблице ниже может также использоваться PUT. Stronghold использует нестандартный HTTP-метод LIST и позволяет выполнять запросы операций со списками с помощью глагола GET и параметра запроса ?list=true, поэтому для каждого упоминания LIST в таблице ниже можно также использовать GET с ?list=true.

Следующие пути требуют наличия в политике root-токена или возможностей sudo:

Путь HTTP-метод Описание
auth/token/accessors LIST Выводит список идентификаторов доступа (accessors) для всех текущих служебных токенов Stronghold
auth/token/create POST Создаёт периодический или «осиротевший» (orphan) токен (через опцию period или no_parent)
pki/root DELETE Удаляет текущий ключ CA (механизм секретов PKI)
pki/root/sign-self-issued POST Использует настроенный сертификат CA для подписи самостоятельно выпущенного сертификата (механизм секретов PKI)
sys/audit GET Выводит список включённых устройств аудита
sys/audit/:path POST, DELETE Включает или удаляет устройство аудита
sys/auth/:path GET, POST, DELETE Управление методами аутентификации (включение, чтение и удаление)
sys/auth/:path/tune GET, POST Управление методами аутентификации (включение, чтение, удаление и настройка)
sys/config/auditing/request-headers GET Выводит список заголовков запросов, для которых настроен аудит
sys/config/auditing/request-headers/:name GET, POST, DELETE Управление заголовками аудита (создание, обновление, чтение и удаление)
sys/config/cors GET, POST, DELETE Настройка параметров CORS
sys/config/ui/headers GET, LIST Настройка параметров графического интерфейса
sys/config/ui/headers/:name POST, DELETE Настройка кастомных HTTP-заголовков для использования в графическом интерфейсе
sys/internal/inspect/router/:tag GET Проверяет внутренние компоненты маршрутизатора Stronghold. Допустимые значения для tag: root, uuid, accessor или storage
sys/leases/lookup/:prefix LIST Выводит список идентификаторов аренды
sys/leases/revoke-force/:prefix POST Отзывает все секреты или токены, игнорируя ошибки бэкенда
sys/leases/revoke-prefix/:prefix POST Отзывает все секреты, созданные под указанным префиксом
sys/plugins/catalog/:type/:name GET, POST, DELETE Регистрирует новый плагин или читает/удаляет существующий
sys/raw:path GET, POST, DELETE Используется для доступа к необработанному базовому хранилищу в Stronghold
sys/raw:prefix GET, LIST Возвращает список ключей для заданного префикса пути
sys/remount POST Перемещает уже смонтированный бэкенд в новую точку монтирования
sys/replication/reindex POST Запускает повторную индексацию локального хранилища данных
sys/replication/performance/primary/secondary-token POST Генерирует токен вторичной активации performance
sys/replication/dr/primary/secondary-token POST Генерирует токен вторичной активации DR
sys/rotate POST Запускает ротацию ключа шифрования бэкенда
sys/seal POST Запечатывает хранилище Stronghold
sys/step-down POST Заставляет узел отказаться от активного статуса
sys/storage/raft/snapshot-auto/config LIST Выводит список конфигураций с указанием имён
sys/storage/raft/snapshot-auto/config/:name GET, POST, DELETE Создаёт или обновляет конфигурацию с указанным именем

Токены

У токенов есть два набора политик: политики идентификации, которые вычисляются на основе сущности и её групп, а также политики токенов, которые либо определяются на основе метода аутентификации, либо, в случае явного создания токена через API, являются входной точкой для создания токена. Всё нижеследующее касается исключительно политик токенов. Политиками идентификации нельзя управлять, кроме как изменяя базовые сущности, группы и членство в группах.

Привязка к политикам происходит во время создания токенов. Например:

d8 stronghold token create -policy=dev-readonly -policy=logs

Обычно можно указывать только те политики, которые присутствуют в политиках текущего токена (родительского токена). Однако root-пользователи могут назначать любые политики.

Не существует способа изменить политики, связанные с токеном, после того как токен был выпущен. Чтобы получить новый набор политик, токен должен быть отозван и получен новый.

Парсинг содержимого политик происходит в режиме реального времени при каждом использовании токена. Это приводит к тому, что если политика была изменена, изменённые правила будут принудительно задействованы в следующий раз, когда токен с этой политикой будет использован при выполнении запроса в Stronghold.