summaryrefslogtreecommitdiff
path: root/doc/authz/SAML.md
blob: df51f6ae2cbf2052f58e443d2b1aa4a6573d9d38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# SAML 2.0

Enable instance level SAML configuration in Terraform Cloud to use HCP as the
identity provider. This allows for service provider initiated and identity
provider intiated authentication. The default set of SAML attributes that the
instance level will accept will be extened to allow capture of a subjects
current set or permissions.

E.g.

This is an incomplete example with many attributes removed to make it easier to
`consume`. (See what I did there?)

```xml
<?xml version="1.0"?>
<Response Version="2.0" Destination="https://app.terraform.io/sso/saml/acs">
  <Issuer>https://id.terraform.io/metadata.xml</Issuer>
  <Status>
    <StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </Status>
  <Assertion Version="2.0">
    <Issuer>https://idp.terraform.io/metadata.xml</Issuer>
    <Subject>
      <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">mo.khan@hashicorp.com</NameID>
    </Subject>
    <Conditions NotBefore="2022-03-30T18:50:39Z" NotOnOrAfter="2022-03-30T21:50:39Z">
      <AudienceRestriction>
        <Audience>https://app.terraform.io/sso/saml/metadata</Audience>
      </AudienceRestriction>
    </Conditions>
    <AuthnStatement AuthnInstant="2022-03-30T18:50:39Z">
      <AuthnContext>
        <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
      </AuthnContext>
    </AuthnStatement>
    <AttributeStatement>
      <Attribute Name="Permissions">
        <AttributeValue>terraform.teams.create</AttributeValue>
        <AttributeValue>terraform.teams.read</AttributeValue>
        <AttributeValue>terraform.workspaces.read</AttributeValue>
      </Attribute>
    </AttributeStatement>
  </Assertion>
</Response>
```

The general idea is that the SAML assertion will include a `Permissions`
attribute that can align with the permissions naming scheme from HCP that can be
used for authorizing access to resources for the current session. Terraform
Cloud will need to maintain this list of permissions and associate it with the
current session token (i.e. cookie, api key, etc).

## TFE Approach

<!-- In this idea, how do we prevent TFE customers from being hurt? -->

In TFE mode, the Terraform rails app will act as both the SAML Service Provider
and SAML Identity Provider by default. Organizations can override the default
SAML Identity Provider by setting up their own. In that scenario, the SAML
Assertion will not contain a list of permissions and can fall back to the
existing authz policies.

## Coupling Assessment

<!-- In this idea, how coupled is TFC to HCP at runtime? -->

TFC will be coupled to the SAML `Permissions` attribute if it is present.
If it is not present then access falls back to the current users role and
permissions are assigned based on todays implicit mapping of role to
permission/claim.

## Expected Benefits

<!-- Not exhaustive, but what makes this compelling? -->

This minimizes the effort involved by utilizing a feature that is available
today but enables it by default to point to HCP as the SAML Idp.

## Expected Downsides

<!-- Not exhaustive, but what are some initial concerns? -->

SAML. The SAML Assertion Consumer Service endpoint is an attack vector that
needs to be hardened by ensuring we:

* rate limit
* prevent reusing assertions.
* prevent golden SAML style attacks that abuse XML parsers.

## Investigation Goal

<!-- What do we need to do to understand this better? Is it feedback from others, is it a technical spike, is it a document? -->

Spike out a flow where Permissions are delivered as attributes and mapped to
existing roles. I would want to list out the current TFC roles and then compile
a list of discrete permissions using the permission naming scheme suggested in
[HCP-104: Permission Naming Convention][1]

[1]: https://docs.google.com/document/d/1ZKBRVBKqZU_l4WcKLugYgY_IUACM4SGHWpnJAuWUf70