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

GCE Authenticator #1711

Closed
InbalZilberman opened this issue Jul 27, 2020 · 4 comments
Closed

GCE Authenticator #1711

InbalZilberman opened this issue Jul 27, 2020 · 4 comments

Comments

@InbalZilberman
Copy link
Contributor

InbalZilberman commented Jul 27, 2020

Feature Overview

The GCE auth method allows Google Compute Engine (GCE) instances running in Google Cloud Platform to authenticate to DAP/Conjur enable them to fetch secrets. We need authenticate these entities against the Google Cloud APIs.

It is a custom that GCP resources are provided with Google Cloud IAM - Cloud Identity and Access Management (IAM) are mostly handled using service accounts. Hence, we will authenticate resources according to their service account properties.

One can create a GCE even without a service account.

Process Logic for GCE

  1. Martin, conjur admin, define gce authenticator named "mygce"
- !policy
  id: conjur/authn-gce/mygce
  body:
  - !webservice
  
  - !variable
    id: provider-uri
        
  - !group apps
    annotations:
      description: Group of hosts that can authenticate using the authn-gce/<service-id> authenticator
    
  - !permit
    role: !group apps
    privilege: [ read, authenticate ]
    resource: !webservice
  1. Martin, conjur admin, or Eva, developer with permissions to Conjur define host
- !policy
  id: <policy-id>
  body:
    - !group
 
    - &hosts
      - !host
        id: myapp
        annotations:
        
          authn-gce/project-id: <project-id>
          authn-gce/service-account-id: <service-account-id>
          authn-gce/service-account-email: <service-account-email>
           
    - !grant
      role: !group
      members: *hosts
          
- !grant
  role: !group /conjur/authn-gce/mygce/apps
  member: !group <policy-id>

Constraints
one of the following should be provided
project-id OR service-account-id OR service-account-email

Some info on project_id
Project ID: A customizable unique identifier for your project.
The project ID is a unique, user-assigned ID that can be used by Google APIs. If you do not specify a project ID
during project creation, a project ID will be generated automatically.
The project ID must be a unique string of 6 to 30 lowercase letters, digits, or hyphens. It must start with a
letter, and cannot have a trailing hyphen. You cannot change a project ID once it has been created.

  1. The app developer, Eva, should retrieve JWT using audience of Conjur
  • The audience should be static - can be determined in design phase

GCE requests its unique identity token (JWT) with format full from the metadata server and specifies the audience of the token to conjur

curl \ --header "Metadata-Flavor: Google" \ --get \ --data-urlencode "audience=conjur" \ --data-urlencode "format=full" \ "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity"

  1. As a result JWT is received
    GCE token:
    eyJhbGciOiJSUzI1NiIsImtpZCI6IjRlNGViZTQ4N2Q1Y2RmMmIwMjZhM2IyMjlkODZmMGQ0MjU4NDQ5ZmUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJo
    wZXIuZ3NlcnZpY2V...8vSRM1UhkbWIgTK7EE7ewbGZ0BUjMBcLyHcNPZjLebpm2dRSV4aRwwdnTdY2XxFGCOge19O8FTaF0Awv-FupLKwfTqvG6RUv49zABQGQpm
    uOp13XYZ6NnORNBuFG6YKs5udBSm2HVP4fyHGWMj4NMwxmKljG3xKAmrhU_xOQZt11TuTfe_vnqp7pt1gtXmdAH9Q5sHqfNODozPAkQyUqO5jmjFJ16

  2. Decrypt JWT fro GCE

{
  "aud": "http://conjur",
  "azp": "1109871298",
  "email": "[email protected]",
  "email_verified": true,
  "exp": 1595160638,
  "google": {
    "compute_engine": {
      "instance_creation_timestamp": 1595766,
      "instance_id": "43405087601530",
      "instance_name": "vm-for-gcp",
      "project_id": "eng-serenity-2313",
      "project_number": 7161458341,
      "zone": "us-central1-a"
    }
  },
  "iat": 1595157038,
  "iss": "https://accounts.google.com",
  "sub": "110987294251917851298"
}

  1. Call the /authn-gce/mygce
    POST https:///authn-gce/mygce//myapp/authenticate
    with JWT

Header
Content-Type: application/x-www-form-urlencoded
Body
The body must include the GCP access token for GCE instance.
jwt=eyJhbGciOiJSUzI1NiIs......uTonCA

The authenticator is expected to use the certificate of GCP to decode the JWT and then compare the host annotations to the fields in the JWT as follows:

  1. Validate the JWT with the provider (according to claim, experations....)
  2. Validate the audience is Conjur
  3. Validate that the host has the right host identity as written in the JWT
JWT field Correlated host annotation Remarks
email authn-gce/service_account_email
google/compute_engine/project_id authn-gce/project_id
sub authn-gce/service_account_id

Open issues

  1. global key pair vs service account key pair -

    1. GCE identity - from the "metadata" API

      https://cloud.google.com/compute/docs/storing-retrieving-metadata#default

      a. Uses the global Google certificate - https://www.googleapis.com/oauth2/v1/certs.

    b. IAM identity - from the service account keys API - "https://www.googleapis.com/service_accounts/v1/metadata/x509/%s?alt=json"
    https://cloud.google.com/iam/docs/creating-managing-service-account-keys

    1. Can we first check first (a) and if fails try (b) ?

    2. Can the provider-uri be hard coded and not need user input? maybe a global config?

    3. How do we validate the JWT?

Audit

All authentications calls should be audited.

Status API

Any new Authenticator that is added has it's status API

Logging

Are there new log files for this feature? If so, specify how they are called, where, if / how they are rotated and when they are enabled.

Support Matrix

  • Latest DAP and OSS
@orenbm
Copy link
Member

orenbm commented Jul 27, 2020

one of the following should be provided
instance-name OR project-id OR service-account-id OR service-account-email

@InbalZilberman just to verify: we can have one and only one, correct? you can't have any combination and you can't have no constraints at all.

@orenbm
Copy link
Member

orenbm commented Jul 27, 2020

The audience should be static - can be determined in design phase

@InbalZilberman again verifying that i understand correctly - the solution design should introduce a static audience (e.g conjur) and it will be documented. this audience will be provided by the user when they request a JWT and we will verify it in our code.

Writing down some UX options for this for the design:

  • have it hard-coded
  • have it set as a variable in the authenticator policy
  • have it set as an annotation in the host definition in the policy
  • have it as an optional of the above with a default hard-coded value

@AndrewCopeland
Copy link

@InbalZilberman
Host annotation should use - instead of _. Example authn-gcp/service_account_email should be authn-gcp/service-account-email. This would stay consistent with authn-azure.

Can you have the same instance_name in different zones? Same applies with project_id?

    "compute_engine": {
      "instance_creation_timestamp": 1595766,
      "instance_id": "43405087601530",
      "instance_name": "vm-for-gcp",
      "project_id": "eng-serenity-2313",
      "project_number": 7161458341,
      "zone": "us-central1-a"
    }

@sashaCher
Copy link
Contributor

project-id OR service-account-id OR service-account-email

@InbalZilberman What is the reason of OR? Are those parameters mutually exclusive?

@eranha eranha changed the title GCP authenticator - Design GCP authenticator Aug 19, 2020
@eranha eranha changed the title GCP authenticator GCE Authenticator Aug 19, 2020
@Tovli Tovli closed this as completed Oct 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants