skip to Main Content

I’m trying to read timestream data from web app for public use.
I followed this tutorial from AWS to allow any user to see the data on web browser.
After that, I followed this github issue since discovering endpoints was failing.

The problem I’m having now is that it returns these errors now.

POST https://query.timestream.us-west-2.amazonaws.com/ 403 (Forbidden)
Uncaught (in promise) AccessDeniedException: 
User: arn:aws:sts::<number here>:assumed-role/Cognito_izunumaUnauth_Role/CognitoIdentityCredentials 
is not authorized to perform: timestream:DescribeEndpoints because no session policy allows 
the timestream:DescribeEndpoints action

I have already attached a policy to Cognito_izunumaUnauth_Role to allow timestream:DescribeEndpoints and checked that it works on simulator on IAM, so I don’t know what to do to resolve this error.

the code looks like this in my react app now.

import * as AWS from "@aws-sdk/client-timestream-query";
import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity";
import {
  fromCognitoIdentityPool,
} from "@aws-sdk/credential-provider-cognito-identity";
import {useEffect} from 'react';

function App() {

  useEffect(()=>{
    (async () => {
      const endpointsQueryClient = new AWS.TimestreamQuery({ 
        region: "us-west-2",
        credentials: fromCognitoIdentityPool({
          client: new CognitoIdentityClient({ region: "us-west-2" }),
          identityPoolId: "<IDENTITY_POOL_ID>",
        })
      });
      const qClientResponse = await endpointsQueryClient.describeEndpoints({});
      console.log(qClientResponse);

      const queryClient = new AWS.TimestreamQuery({
        region: "us-west-2",
        credentials: fromCognitoIdentityPool({
          client: new CognitoIdentityClient({ region: "us-west-2" }),
          identityPoolId: "<IDENTITY_POOL_ID>",
        }),
        endpoint: `https://${qClientResponse.Endpoints[0].Address}`,
      });

      const QueryString = `SELECT * FROM solarpanel_test.solarpanel_test WHERE time between ago(30000m) and now() ORDER BY time DESC LIMIT 200`;
      console.log(await queryClient.query({ QueryString }));

    })()
  },[])

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

I’m new to AWS, so any suggestion would help.

2

Answers


  1. I understand your concern, aws has fine grain policies for each operation.
    one for describe endpoint another for select then another for preparequery and so on…
    you will also need to add SELECT Policy here.
    After describe end point you are running select query.
    There are nearly 7 actions for read policy. while Describepolicies (describeEndpoint/ ListDatabases) are only to list database/tables but not to read data.

    Login or Signup to reply.
  2. This is the exact issue that I encountered, I thought it is something about authorization, yeah it is quite right but, this error refers to your role, so I use STSClient here,use that role credentials to use the other features of @aws-sdk

    const { STSClient, AssumeRoleCommand } = require("@aws-sdk/client-sts");
    
    const params = {
      RoleArn: "<role>",
      RoleSessionName: "<name>",
    };
    const clientRole = new STSClient({
      region: "us-west-2",
      credentials: aws_creds,
    });
    const roleCommand = new AssumeRoleCommand({
      RoleArn: "<role>",
      RoleSessionName: "<name>",
    })
    const role = await clientRole.send(roleCommand);
    
    const role_creds = {
      accessKeyId: role.Credentials.AccessKeyId,
      secretAccessKey: role.Credentials.SecretAccessKey,
      sessionToken: role.Credentials.SessionToken,
    };
    const query = `SELECT * FROM db.table ORDER BY column DESC LIMIT 5`;
    
    const timestreamQuery = new TimestreamQueryClient({
      region: "us-west-2",
      credentials: role_creds,
    });
    const queryCommand = new QueryCommand({QueryString: query})
    
    // use it like `timestreamQuery.send(queryCommand, (err, data)=> { ... })`
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search